From 51c0ee5ac88af5f4f7425dca58169faa9bb010ec Mon Sep 17 00:00:00 2001 From: lawrence3699 Date: Thu, 2 Apr 2026 21:42:49 +1100 Subject: [PATCH] fix: handle unprotected JSON parsing in mime detection and Steel Browser API Wrap json.loads() in guess_mime_type_from_bytes() and response.json() in Steel Browser session methods with try-except to prevent unhandled exceptions from crashing callers when responses contain invalid JSON or non-UTF-8 data. --- dynamiq/nodes/tools/stagehand.py | 15 +++++++++++++-- dynamiq/nodes/tools/utils.py | 7 +++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/dynamiq/nodes/tools/stagehand.py b/dynamiq/nodes/tools/stagehand.py index f00cb9462..aeb561642 100644 --- a/dynamiq/nodes/tools/stagehand.py +++ b/dynamiq/nodes/tools/stagehand.py @@ -255,14 +255,25 @@ def _upload_file_bytes_to_steel_browser_session(self, session_id: str, file_byte files = {"file": (file_name, io.BytesIO(file_bytes))} response = requests.post(url, headers=self._get_steel_browser_headers(), files=files, timeout=self.timeout) response.raise_for_status() - return response.json() + try: + return response.json() + except ValueError as e: + logger.error(f"Failed to parse JSON from Steel Browser upload response: {e}") + raise ToolExecutionException( + f"Steel Browser API returned invalid JSON after file upload: {e}", + recoverable=True, + ) def _list_steel_browser_session_files(self, session_id: str) -> list[dict]: """List all files in the Steel Browser session's filesystem.""" url = f"{self._get_steel_browser_base_url()}/sessions/{session_id}/files" response = requests.get(url, headers=self._get_steel_browser_headers(), timeout=self.timeout) response.raise_for_status() - payload = response.json() + try: + payload = response.json() + except ValueError as e: + logger.error(f"Failed to parse JSON from Steel Browser files response: {e}") + return [] if isinstance(payload, dict): logger.info(f"Steel session files: {payload.get('data') or []}") return payload.get("data") or [] diff --git a/dynamiq/nodes/tools/utils.py b/dynamiq/nodes/tools/utils.py index af3bdd1cb..663041da6 100644 --- a/dynamiq/nodes/tools/utils.py +++ b/dynamiq/nodes/tools/utils.py @@ -74,8 +74,11 @@ def guess_mime_type_from_bytes(data: bytes, filename: str = None) -> str: elif data.startswith(b" 1):