fix: make Browserbase sessions re-attachable by ID (STG-2446)#195
Open
sameelarif wants to merge 1 commit into
Open
fix: make Browserbase sessions re-attachable by ID (STG-2446)#195sameelarif wants to merge 1 commit into
sameelarif wants to merge 1 commit into
Conversation
Tool calls carried no session identifier, so navigate/act/observe/extract relied entirely on the in-process SessionManager's activeSessionId being preserved across MCP calls. On the hosted, multi-replica server (or when a client rotates/drops the Mcp-Session-Id) a follow-up call lands on a fresh SessionManager that has no record of the session created by `start`, and getStagehand throws "No session found for ID" — surfacing to clients like ChatGPT as "No active session". - start now accepts an optional sessionId to resume an existing Browserbase session (via the already-present resumeSessionId path). - navigate/act/observe/extract accept an optional sessionId, passed through to context.getStagehand(sessionId). - SessionManager.getSession reconnects to an unknown non-default session by ID (browserbaseSessionID resume) instead of returning null, so any replica can rehydrate the session the client holds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
Re: STG-2446 escalation. The "No active session" failure in the ChatGPT Workspace is served by the hosted MCP in
browserbase/core(apps/stagehand-api-v3/mcp/), which does not use this OSS package. The escalation fix (reattach-by-sessionId, ported into the code that actually servesmcp.browserbase.com) is browserbase/core#10363, validated on local dev.This PR remains valuable as self-hosted / OSS parity for
@browserbasehq/mcp, but it does not affect the hosted endpoint. Recommend unlinking it from STG-2446 so it doesn't auto-close the escalation on merge.Problem
Users hit "No active session" when driving the Browserbase MCP server from ChatGPT:
startcreates a session successfully, but the follow-upnavigatefails even though the session is live.Root cause: browser-session state was connection-scoped and unrecoverable.
navigate/act/observe/extractall resolved their target viacontext.getStagehand()→SessionManager.activeSessionId.start→navigatewas the in-processSessionManagerstaying alive across MCP calls, keyed by theMcp-Session-Idtransport header.mcp.browserbase.com), a follow-up request can land on a different replica — or a client can rotate/drop theMcp-Session-Id. Either way the call hits a freshSessionManagerwith no record of the sessionstartcreated, andgetStagehandthrowsNo session found for ID: …→ surfaced to ChatGPT as "No active session."createNewBrowserSession(..., resumeSessionId)) but was dead code — never called with a resume ID and never exposed through any tool.Fix
Make sessions re-attachable by Browserbase session ID so correctness no longer depends on sticky routing:
startaccepts an optionalsessionIdto resume an existing Browserbase session (returns the id as before).navigate/act/observe/extractaccept an optionalsessionId, passed through tocontext.getStagehand(sessionId). Omitting it preserves the existing active-session behavior.SessionManager.getSessionreconnects to an unknown non-default session by ID (via the existingbrowserbaseSessionIDresume path) instead of returningnull, so any replica can rehydrate the session the client holds.Verification
tsc --noEmit,eslint, andpnpm buildall clean;vitest run— 17/17 pass (added schema coverage for the newsessionIdparam).starton transport A, thennavigateon a fresh transport B (no knowledge of A) withsessionIdset. Server logs confirm the reconnect path:Navigation succeeded where it previously threw "No session found for ID".
Note
This removes the dependency on sticky routing for correctness, but the hosted transport's
streamableSessionsmap is still per-process in-memory. Pairing this with sticky sessions or a shared session store at the infra layer (outside this repo) is still recommended sostart-created sessions aren't stranded on one replica.🤖 Generated with Claude Code