What?
Spawning a second named --session while the global profile key is set in ~/.agent-browser/config.json causes Chrome to crash silently. The agent-browser daemon survives the Chrome crash, leaving stale .pid / .engine / .sock state files in ~/.agent-browser/. The user-facing error is misleading:
✗ Chrome exited early (exit code: 0) without writing DevToolsActivePort
Hint: try passing --args "--no-sandbox" if Chrome crashes silently in your environment
The real cause is a Chrome --user-data-dir lock collision — both sessions inherit the same profile path from config, and Chrome enforces a single-instance lock per --user-data-dir. --no-sandbox does not address this; it sends users down the wrong diagnostic path.
Reproducer (macOS, agent-browser installed via npm):
- Set in
~/.agent-browser/config.json:
{
"profile": "/Users/<you>/.agent-browser/profiles/my-profile",
"headed": true
}
- Run two sessions:
agent-browser --session a open https://example.com # works
agent-browser --session b open https://example.com # silent Chrome crash
agent-browser session list shows both daemons alive even though session b's Chrome never started. pgrep -afl "Chrome for Testing" | grep -v Helper | grep -v crashpad shows only the session-a Chrome.
Workaround that does work: Pass --profile <different-dir> on the second session's first command — but only effective on a fresh daemon. Subsequent commands to that session without --profile re-read config, re-collide, re-crash. Net: every command to a non-default session needs the explicit --profile flag (or env var AGENT_BROWSER_PROFILE=<dir>).
Why?
The flagship multi-session example in core/references/session-management.md ("Concurrent Scraping") shows --session site1 / site2 / site3 working without any per-call --profile. That contract is silently violated as soon as a user adds profile to their config — which the SKILL.md itself encourages ("Default profile + idleTimeout/contentBoundaries/maxOutput are wired in ~/.agent-browser/config.json. Bare agent-browser open <url> picks them up. Do not pass --profile.").
The two recommended-practice surfaces collide:
- Single-session ergonomic: pin
profile in config so default-session login state persists across runs.
- Multi-session ergonomic: name sessions and let auto-isolation work.
Both are advertised; together they break. No diagnostic message helps the user connect crash → profile collision.
Three concrete asks:
- Detect the
--user-data-dir lock collision specifically and emit a targeted error, e.g.: session "b" cannot use profile X — already locked by session "a". Replace or augment the current "Chrome exited early" message in that code path.
- Drop the
--no-sandbox hint when the underlying cause is a lock collision — it sends users down the wrong path.
- Either auto-suffix the config
profile path with the session name when --session <name> is used (e.g., profile → profile-<session>/), or document the multi-session ↔ config-profile incompatibility prominently in session-management.md and add a profiles mapping to the config schema ({ "profiles": { "default": "/path/a", "scrape": "/path/b" } }).
Source
💻 core/references/session-management.md — "Concurrent Scraping" example (lines 101–122) — advertises --session a/b/c parallel pattern without --profile.
💻 SKILL.md — "Default profile" + "Hot-daemon footgun" note — tells users to pin profile in config and not pass --profile. The two pieces of advice are mutually incompatible when combined with --session.
💻 Config schema (https://agent-browser.dev/schema.json) — profile is a single string with no per-session mapping; no way to express "use isolated profile per session" at config level.
🗒️ Reproduced on macOS 14.x (Darwin 24.3.0), agent-browser installed via npm i -g agent-browser, Chrome for Testing 148.0.7778.97 bundled by agent-browser install. Two daemon PIDs alive (agent-browser session list confirms), but only one Chrome main process (pgrep -afl "Chrome for Testing" | grep -v Helper) — the second session's Chrome exited before writing DevToolsActivePort.
🤖
What?
Spawning a second named
--sessionwhile the globalprofilekey is set in~/.agent-browser/config.jsoncauses Chrome to crash silently. The agent-browser daemon survives the Chrome crash, leaving stale.pid/.engine/.sockstate files in~/.agent-browser/. The user-facing error is misleading:The real cause is a Chrome
--user-data-dirlock collision — both sessions inherit the sameprofilepath from config, and Chrome enforces a single-instance lock per--user-data-dir.--no-sandboxdoes not address this; it sends users down the wrong diagnostic path.Reproducer (macOS, agent-browser installed via npm):
~/.agent-browser/config.json:{ "profile": "/Users/<you>/.agent-browser/profiles/my-profile", "headed": true }agent-browser session listshows both daemons alive even though sessionb's Chrome never started.pgrep -afl "Chrome for Testing" | grep -v Helper | grep -v crashpadshows only the session-aChrome.Workaround that does work: Pass
--profile <different-dir>on the second session's first command — but only effective on a fresh daemon. Subsequent commands to that session without--profilere-read config, re-collide, re-crash. Net: every command to a non-default session needs the explicit--profileflag (or env varAGENT_BROWSER_PROFILE=<dir>).Why?
The flagship multi-session example in
core/references/session-management.md("Concurrent Scraping") shows--session site1 / site2 / site3working without any per-call--profile. That contract is silently violated as soon as a user addsprofileto their config — which the SKILL.md itself encourages ("Default profile + idleTimeout/contentBoundaries/maxOutput are wired in~/.agent-browser/config.json. Bareagent-browser open <url>picks them up. Do not pass--profile.").The two recommended-practice surfaces collide:
profilein config so default-session login state persists across runs.Both are advertised; together they break. No diagnostic message helps the user connect crash → profile collision.
Three concrete asks:
--user-data-dirlock collision specifically and emit a targeted error, e.g.:session "b" cannot use profile X — already locked by session "a". Replace or augment the current "Chrome exited early" message in that code path.--no-sandboxhint when the underlying cause is a lock collision — it sends users down the wrong path.profilepath with the session name when--session <name>is used (e.g.,profile→profile-<session>/), or document the multi-session ↔ config-profile incompatibility prominently insession-management.mdand add aprofilesmapping to the config schema ({ "profiles": { "default": "/path/a", "scrape": "/path/b" } }).Source
💻
core/references/session-management.md— "Concurrent Scraping" example (lines 101–122) — advertises--session a/b/cparallel pattern without--profile.💻
SKILL.md— "Default profile" + "Hot-daemon footgun" note — tells users to pinprofilein config and not pass--profile. The two pieces of advice are mutually incompatible when combined with--session.💻 Config schema (
https://agent-browser.dev/schema.json) —profileis a single string with no per-session mapping; no way to express "use isolated profile per session" at config level.🗒️ Reproduced on macOS 14.x (Darwin 24.3.0), agent-browser installed via
npm i -g agent-browser, Chrome for Testing 148.0.7778.97 bundled byagent-browser install. Two daemon PIDs alive (agent-browser session listconfirms), but only one Chrome main process (pgrep -afl "Chrome for Testing" | grep -v Helper) — the second session's Chrome exited before writingDevToolsActivePort.🤖