Skip to content

fix: Correctly handle JSON and multipart request bodies#340

Closed
aryanjsingh wants to merge 1 commit intobrowserbase:mainfrom
aryanjsingh:fix/issue-316-v360-sessionsstart-with-cdpurl-fails-to-
Closed

fix: Correctly handle JSON and multipart request bodies#340
aryanjsingh wants to merge 1 commit intobrowserbase:mainfrom
aryanjsingh:fix/issue-316-v360-sessionsstart-with-cdpurl-fails-to-

Conversation

@aryanjsingh
Copy link
Copy Markdown

@aryanjsingh aryanjsingh commented Apr 3, 2026

Summary

This pull request fixes a regression in v3.6.0 where connecting to an existing browser via cdpUrl failed. The root cause was a change that switched from httpx's json= parameter to content=, which prevented the Content-Type header from being set correctly.

This fix refactors the request building logic to properly distinguish between JSON and multipart requests. It ensures that json_data is correctly included in multipart requests and that the Content-Type: application/json header is reliably sent for JSON requests, resolving both the primary issue and a secondary regression where JSON data was dropped during file uploads.

Changes

  • src/stagehand/_base_client.py: Refactored the _build_request method in src/stagehand/_base_client.py to correctly handle request body and file serialization. The previous logic was convoluted, leading to dropped JSON data in multipart requests and incorrect Content-Type headers for JSON requests. The new implementation clearly distinguishes between multipart and JSON requests based on the presence of files, ensuring both are constructed correctly.

Related Issue

Closes #316


Summary by cubic

Fixes a v3.6.0 regression that broke connecting to an existing browser via cdpUrl by correctly handling JSON and multipart bodies. Ensures JSON requests set Content-Type: application/json and JSON data isn’t dropped during file uploads. Closes #316.

  • Bug Fixes
    • Refactored _build_request to detect multipart via files and build bodies accordingly.
    • JSON-only: send JSON as content and keep Content-Type: application/json. Multipart: remove Content-Type so httpx sets the boundary and serialize json_data into form fields.
    • Added checks to block incompatible combinations (content with json_data or files).

Written for commit 09679db. Summary will update on new commits. Review in cubic

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Confidence score: 1/5

  • src/stagehand/_base_client.py appears truncated with invalid Python syntax, which will cause immediate import failure and break runtime behavior as soon as this module is loaded.
  • This is a merge-blocking risk: severity and confidence are both 10/10, and the failure mode is concrete and user-facing rather than speculative.
  • Pay close attention to src/stagehand/_base_client.py - truncated content must be restored to valid syntax before merge.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/stagehand/_base_client.py">

<violation number="1" location="src/stagehand/_base_client.py:830">
P0: `_base_client.py` was truncated, leaving invalid Python syntax that causes immediate import failure.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant App as Application/Caller
    participant Client as _base_client (SDK)
    participant HTTPX as httpx Library
    participant API as External API / Browser

    Note over Client: _build_request() logic

    App->>Client: request(json_data, files, content)
    
    rect rgb(240, 240, 240)
        Note over Client: NEW: Validation Logic
        alt options.content provided with json_data OR files
            Client-->>App: raise TypeError (Incompatible inputs)
        end
    end

    alt Files are present (Multipart Flow)
        Client->>Client: CHANGED: Remove "Content-Type" header
        Note right of Client: Allows httpx to generate <br/>correct boundary header
        opt json_data exists
            Client->>Client: CHANGED: Serialize json_data into form 'data'
        end
        Client->>HTTPX: Request(method, url, data=serialized, files=files)
    
    else No files present (Standard JSON Flow)
        Client->>Client: CHANGED: Serialize json_data to JSON string
        Note right of Client: Ensures Content-Type: application/json <br/>remains in headers
        Client->>HTTPX: Request(method, url, content=json_string)
    end

    Client->>HTTPX: send(request)
    HTTPX->>API: HTTP Request (Correct Headers + Body)
    API-->>HTTPX: HTTP Response
    HTTPX-->>Client: Response Object
    Client-->>App: Parsed Data
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

"""
merged = {**obj1, **obj2}
return {key: value for key, value in merged.items() if not isinstance(value, Omit)}
t No newline at end of file
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: _base_client.py was truncated, leaving invalid Python syntax that causes immediate import failure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/stagehand/_base_client.py, line 830:

<comment>`_base_client.py` was truncated, leaving invalid Python syntax that causes immediate import failure.</comment>

<file context>
@@ -848,1280 +827,4 @@ def __init__(
-    """
-    merged = {**obj1, **obj2}
-    return {key: value for key, value in merged.items() if not isinstance(value, Omit)}
+        t
\ No newline at end of file
</file context>
Fix with Cubic

@aryanjsingh aryanjsingh closed this Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v3.6.0: sessions.start() with cdpUrl fails to connect to already-launched browser

1 participant