Skip to content

fix(browser): named browser_exec sessions compose with every backend - #86916

Merged
teknium1 merged 1 commit into
mainfrom
fix/browser-exec-named-sessions-compose
Aug 15, 2026
Merged

fix(browser): named browser_exec sessions compose with every backend#86916
teknium1 merged 1 commit into
mainfrom
fix/browser-exec-named-sessions-compose

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

browser_exec named sessions (session=<name>) now isolate concurrent browser work on every backend, not just Browser Use cloud — parallel subagents and simultaneous chats stop clobbering one shared daemon socket. Root cause: the tool set BU_NAME and then skipped backend resolution entirely, so the name was cloud-only and all local/CDP traffic funneled through the single default daemon. Reported by @shantanugoel on X.

Changes

  • tools/browser_use_cli.py: named sessions compose with _resolve_backend_cdp instead of bypassing it. BU_NAME keeps namespacing the harness daemon (upstream already isolates socket/log/pid per name); the /browser connect CDP override is now honored by named sessions; on provider backends (Browserbase, Firecrawl, Nous gateway) the name keys its own provider browser through the shared _get_session_info cache (bu-named-<name> — same name reuses one browser across calls/tasks, different names never collide). Direct-API Browser Use cloud keeps the native named-daemon path (provider resolution would double-session and double-bill).
  • Tool schema + description header rewritten: session=<name> is presented as the isolation mechanism for parallel work on any backend.
  • tests/tools/test_browser_use_cli.py: 3 new tests (compose-with-provider, name-stable-across-tasks, direct-API-BU-still-skips); removed the test pinning the old skip behavior.
  • website/docs/user-guide/features/browser.md: concurrent-sessions paragraph.

Validation

Before After
Named session on provider backend skipped resolution, no browser own cloud browser keyed bu-named-<name>
Named session + /browser connect override ignored, daemon scanned local profiles override exported to the named daemon
Concurrent named sessions, live E2E (real browser-use CLI + headless Chrome) one shared daemon, clobber 2 sessions set + read back distinct page state, PASS
Sabotage run (old behavior restored) new tests fail 2/2, confirming they pin the fix
tests/tools/test_browser_use_cli.py 85 passed 87 passed

Upstream note: full tab-level isolation of multiple named local daemons on one Chrome additionally needs the harness to create a per-name tab instead of attaching to the first page — being submitted to browser-use/browser-harness separately (their issues #375/#582/#604 track the same cluster).

Infographic

Named browser sessions — concurrent browsing unlocked

session=<name> previously set BU_NAME and then skipped backend resolution
entirely — the parameter was documented as cloud-only, so all local/CDP
work funneled through the single default daemon and one IPC socket, and
concurrent sessions (parallel subagents, simultaneous chats) clobbered
each other's browser connection. Reported by @shantanugoel on X.

Now a named session composes with whatever browser source is configured:

- BU_NAME still namespaces the harness daemon (per-name IPC socket, log,
  pid — upstream already isolates these), for local Chrome and CDP.
- The /browser connect CDP override is now exported for named sessions
  too; previously a named daemon ignored it and fell back to scanning
  local Chrome profiles.
- On provider backends (Browserbase, Firecrawl, Nous gateway), the name
  keys its own provider browser via the shared _get_session_info cache
  (bu-named-<name>), so each name gets its own cloud browser, the same
  name reuses one across calls and tasks, and unnamed calls keep the
  per-task key.
- Direct-API Browser Use cloud configs keep the native named-daemon path
  (provider resolution would double-session and double-bill).

Tool schema/description updated so models reach for session=<name> for
parallel work on any backend, not just cloud.

E2E: two named sessions against a real headless Chrome (real browser-use
CLI, BU_CDP_URL) ran concurrently, set distinct page state, and read it
back intact; sabotage run confirms the new tests fail without the fix.
@github-actions

github-actions Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on fb8a4ae — fix(browser): named browser_exec sessions compose with every

⚠️ Warnings

OSV vulnerability scan · View job

5 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 3m59s vs 3m36s (+10.6%). 14 job(s) slower, 10 faster, 1 unchanged.

  • Python tests / Run tests slice 1/12: -28.0s
  • Python tests / Run tests slice 3/12: +22.0s
  • OS-specific tests / Windows-only tests: +18.0s
  • Python tests / Run tests slice 10/12: +12.0s
  • Python tests / Run tests slice 7/12: +10.0s

@teknium1
teknium1 merged commit bb4f680 into main Aug 15, 2026
45 checks passed
@teknium1
teknium1 deleted the fix/browser-exec-named-sessions-compose branch August 15, 2026 11:06
@alt-glitch alt-glitch added type/bug Something isn't working tool/browser Browser automation (CDP, Playwright) P2 Medium — degraded but workaround exists labels Aug 15, 2026
teknium1 added a commit that referenced this pull request Aug 15, 2026
Follow-up to #86916. That fix gave named sessions their own daemon
(socket/log/pid) and their own provider browser — but on a SHARED local
Chrome / CDP browser, a fresh named daemon still attaches to the first
existing page, the same page a sibling daemon may hold. A named session
that never calls new_tab() could still stomp another's tab.

browser_exec now prepends a small preamble to the model's code for named
sessions on shared browsers: once per daemon process (marker keyed by
uid + BU_NAME + daemon pid), it creates a fresh tab via
Target.createTarget and switch_tab()s onto it before any model code
runs. Private per-name browsers (provider-keyed bu-named-<name>, or
direct-API Browser Use cloud) skip the preamble via an internal env
sentinel popped before launch — there's nobody to collide with, and the
extra tab would leak.

Best-effort by design: if the preamble's CDP calls fail, behavior
degrades to pre-fix, never blocks the exec.

E2E against a shared headless Chrome with the STOCK harness: two named
sessions issuing bare js() writes (no new_tab) kept distinct state
(EDGE-A/EDGE-B read back intact); the sabotage run without the preamble
reproduced the clobber (both read EDGE-B). Removes the dependency on the
upstream browser-harness tab-isolation PR for correctness.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Medium — degraded but workaround exists tool/browser Browser automation (CDP, Playwright) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants