-
Notifications
You must be signed in to change notification settings - Fork 103
Description
Description
After upgrading to v3.6.0, passing a cdpUrl in sessions.start() to connect to an already-launched browser no longer works reliably. The session starts but Stagehand fails to attach to the existing browser process.
Root Cause
The change in PR #308 (src/stagehand/_base_client.py) switched request body serialization from httpx's built-in json= parameter to raw content= bytes:
v3.5.0:
else:
kwargs["json"] = json_data if is_given(json_data) else Nonev3.6.0:
elif not files:
kwargs["content"] = openapi_dumps(json_data) if is_given(json_data) and json_data is not None else None
kwargs["files"] = filesWhen httpx receives json=data, it automatically serializes the data and sets Content-Type: application/json. When content=bytes is used instead, httpx does not automatically set the Content-Type header. If the SDK relies on httpx to set this header (rather than setting it explicitly), the server receives the request body without a proper Content-Type: application/json, causing the launchOptions.cdpUrl field to be silently ignored or unparsed — and Stagehand never attaches to the existing browser.
Steps to Reproduce
from stagehand import AsyncStagehand
client = AsyncStagehand(server="local", model_api_key="...", local_ready_timeout_s=30.0)
session = await client.sessions.start(
model_name="openai/gpt-4o",
browser={
"type": "local",
"launchOptions": {
"cdpUrl": "ws://127.0.0.1:9222/devtools/browser/<uuid>",
},
},
)
# Session starts but Stagehand launches a new browser instead of connecting to the existing oneExpected Behavior
Stagehand connects to the already-running browser at the provided cdpUrl.
Actual Behavior
Stagehand ignores the cdpUrl and either launches a new browser or fails to connect.
Workaround
Pin to v3.5.0 until this is resolved:
stagehand==3.5.0
Additional Notes
- The change in
_base_client.pywas introduced to supportexecutionModelserialization with camelCase aliases (by_alias=True) for pydantic models in theexecuteendpoint. The fix for that feature inadvertently changed behavior for all JSON requests. - A secondary regression was also flagged in the same PR: when
filesare provided alongsidejson_data, the JSON body is now silently dropped instead of raising aValueErroras httpx previously did. - The same issue exists in the TypeScript SDK.
Affected version: 3.6.0
Working version: 3.5.0
PS:
Facing the same issue in TS version 3.1.0 and working on version 3.0.8