Summary
With one connected browser everything works. As soon as the extension connects from a second profile of the same browser, CDP breaks and stays broken:
error: browser rejected the underlying CDP call
hint: confirm the tab is still in a loaded state and retry; reloading the tab usually resets a stuck DevTools session
details: Debugger is not attached to the tab with id: <id>
bsk browsers still lists the instance(s), bsk doctor is all ok, non‑CDP calls still work (bsk tab list returns tabs), but navigate / observe / snapshot / screenshot / evaluate all fail. The wedge is sticky: disconnecting (or disabling) the second profile's extension does not recover the first one — only a full browser restart does, and it breaks again the next time a second instance connects.
Environment
- macOS 26.6.2 (Apple Silicon)
- Yandex Browser 26.8.0.1829, reports itself to the extension as
chrome 150.0.0.0
bsk CLI 0.3.0 (aarch64-apple-darwin, release checksum verified), daemon 0.3.0, extension 0.3.0 (browser-skill-extension-v0.3.0-chrome.zip), daemon protocol 1.3, extension protocol 1.3, version_skew: false
- Extension installed unpacked (
chrome://extensions → Load unpacked) in two profiles of the same browser: profile A (Default) and profile B (Profile 2)
- Daemon
ws://127.0.0.1:52800, BSK_HOME=~/.bsk
- Yandex serves both profiles from a single browser process (one main process, no
--profile-directory in its argv) — unlike Chrome, which runs a separate process per profile. Both extension instances therefore have the same extension id (onnlggadnmhcabfamiocjghebiollidk, unpacked) inside one browser process.
Reproduction (two independent cycles, observed)
- Install the unpacked extension in profile A only.
bsk doctor → all ok, 1 browser(s) connected.
- First-use flow works:
bsk session start --no-focus --browser <A> --json # session_id, agent_window_id
bsk navigate https://example.com --session <id> # tab=… reached=load
bsk observe --session <id> # RootWebArea "Example Domain" + text
bsk session stop <id> # ok
- Connect the same extension build in profile B.
bsk doctor → all ok, 2 browser(s) connected.
- Repeat step 2 against either instance (
--browser <A> or --browser <B>) → Debugger is not attached to the tab with id: N.
- Disable/disconnect profile B's extension (leave profile A connected, browser process untouched) → step 2 still fails on profile A.
- Restart the browser → step 2 works again on profile A.
Daemon log of one such cycle (UTC, bsk logs):
13:32:34 INFO browser connected {"id": "…19c", "name": "chrome", "generation": 1} # single instance → CDP OK
13:37:40 INFO browser connected {"id": "…bac", "name": "chrome", "generation": 2} # second instance → CDP broken from here
13:46:04 INFO browser disconnected {"id": "…19c"} # browser restart
13:46:04 INFO browser disconnected {"id": "…bac"}
13:49:15 INFO browser connected {"id": "…19c", "name": "chrome", "generation": 7} # single instance → CDP OK again
13:49:46 INFO browser connected {"id": "…bac", "name": "chrome", "generation": 8} # second instance → CDP broken again
What is ruled out (with evidence)
- Not host permissions / not
about:blank-specific. Fails identically on the auto-created about:blank Agent Window tab and on a user tab with a real https: URL borrowed via bsk tab borrow (borrow/return itself works — the tab is moved into the Agent Window and returned to its original window and index).
- Not a permission grant.
Secure Preferences for both profiles: granted_permissions.api includes debugger, explicit_host: ["<all_urls>"], disable_reasons: [], site access set to "on all sites".
- Not the daemon.
bsk daemon restart (fresh pid) changes nothing; doctor reports daemon running, daemon local process identity, protocol compatible all ok.
- Not extension staleness. Reloading the extension on
chrome://extensions (reload icon on the card) in either profile changes nothing.
- Not version skew. daemon 0.3.0 / extension 0.3.0, both protocol 1.3.
Code-path note (why the error text points at a detach)
In the extension bundle the message can only come from chrome.debugger.sendCommand:
async ensureAttached(tabId) {
…
const r = (async () => {
await this.api.attach({ tabId }, `1.3`);
try { await this.enablePageDomain(tabId); …; this.attachedTabs.add(tabId) }
catch (e) { await this.api.detach({ tabId }).catch(() => {}); throw e } // rollback
})().catch(e => { throw Kt(e) }); // attach failure → wrapped here
…
}
async send(tabId, method, params) {
this.attachedTabs.has(tabId) || await this.ensureAttached(tabId);
return await this.api.sendCommand({ tabId }, method, params); // ← our error comes from here
}
So the failing call is the first sendCommand after a "successful" attach (e.g. the Page.enable that navigate issues) — the browser reports the tab as no longer attached, or the attach was skipped because attachedTabs still claims the tab. With a second instance connected, that seems to happen on every new Agent Window tab.
Hypothesis (not proven)
Both extension instances share one extension id inside one browser process (Yandex's multi-profile model). If Chromium's debugger/permission bookkeeping for the debugger API is keyed per extension id rather than per profile, the two instances would collide and invalidate each other's devtools sessions — which would match the sticky behaviour and the "only a browser restart clears it" observation.
Impact
Keeping the extension in more than one profile (different logins: agency / personal) is the natural multi-profile use case of this tool, and it makes the tool unusable in all profiles until the browser is restarted. A documented single-profile recommendation (or a fix) would help.
Possibly separate, lower priority
After a full browser restart the unpacked extension came back disabled in Default (Secure Preferences: disable_reasons=[1], i.e. DISABLE_USER_ACTION), so bsk doctor reported 0 browsers connected until it was re-enabled on the card. If this reproduces on Chrome too, it is worth a line in AGENT_INSTALL.md (start the daemon, load the extension, and verify it is enabled before bsk doctor).
Summary
With one connected browser everything works. As soon as the extension connects from a second profile of the same browser, CDP breaks and stays broken:
bsk browsersstill lists the instance(s),bsk doctoris allok, non‑CDP calls still work (bsk tab listreturns tabs), butnavigate/observe/snapshot/screenshot/evaluateall fail. The wedge is sticky: disconnecting (or disabling) the second profile's extension does not recover the first one — only a full browser restart does, and it breaks again the next time a second instance connects.Environment
chrome 150.0.0.0bskCLI 0.3.0 (aarch64-apple-darwin, release checksum verified), daemon 0.3.0, extension 0.3.0 (browser-skill-extension-v0.3.0-chrome.zip), daemon protocol 1.3, extension protocol 1.3,version_skew: falsechrome://extensions→ Load unpacked) in two profiles of the same browser: profile A (Default) and profile B (Profile 2)ws://127.0.0.1:52800,BSK_HOME=~/.bsk--profile-directoryin its argv) — unlike Chrome, which runs a separate process per profile. Both extension instances therefore have the same extension id (onnlggadnmhcabfamiocjghebiollidk, unpacked) inside one browser process.Reproduction (two independent cycles, observed)
bsk doctor→ allok,1 browser(s) connected.bsk doctor→ allok,2 browser(s) connected.--browser <A>or--browser <B>) →Debugger is not attached to the tab with id: N.Daemon log of one such cycle (UTC,
bsk logs):What is ruled out (with evidence)
about:blank-specific. Fails identically on the auto-createdabout:blankAgent Window tab and on a user tab with a realhttps:URL borrowed viabsk tab borrow(borrow/return itself works — the tab is moved into the Agent Window and returned to its original window and index).Secure Preferencesfor both profiles:granted_permissions.apiincludesdebugger,explicit_host: ["<all_urls>"],disable_reasons: [], site access set to "on all sites".bsk daemon restart(fresh pid) changes nothing; doctor reportsdaemon running,daemon local process identity,protocol compatibleallok.chrome://extensions(reload icon on the card) in either profile changes nothing.Code-path note (why the error text points at a detach)
In the extension bundle the message can only come from
chrome.debugger.sendCommand:So the failing call is the first
sendCommandafter a "successful" attach (e.g. thePage.enablethatnavigateissues) — the browser reports the tab as no longer attached, or the attach was skipped becauseattachedTabsstill claims the tab. With a second instance connected, that seems to happen on every new Agent Window tab.Hypothesis (not proven)
Both extension instances share one extension id inside one browser process (Yandex's multi-profile model). If Chromium's debugger/permission bookkeeping for the
debuggerAPI is keyed per extension id rather than per profile, the two instances would collide and invalidate each other's devtools sessions — which would match the sticky behaviour and the "only a browser restart clears it" observation.Impact
Keeping the extension in more than one profile (different logins: agency / personal) is the natural multi-profile use case of this tool, and it makes the tool unusable in all profiles until the browser is restarted. A documented single-profile recommendation (or a fix) would help.
Possibly separate, lower priority
After a full browser restart the unpacked extension came back disabled in
Default(Secure Preferences:disable_reasons=[1], i.e.DISABLE_USER_ACTION), sobsk doctorreported0 browsers connecteduntil it was re-enabled on the card. If this reproduces on Chrome too, it is worth a line inAGENT_INSTALL.md(start the daemon, load the extension, and verify it is enabled beforebsk doctor).