Skip to content

chrome.debugger wedges for all profiles once a second profile connects (Yandex Browser 26.8, bsk 0.3.0) #272

Description

@antonbru

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)

  1. Install the unpacked extension in profile A only. bsk doctor → all ok, 1 browser(s) connected.
  2. 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
  3. Connect the same extension build in profile B. bsk doctor → all ok, 2 browser(s) connected.
  4. Repeat step 2 against either instance (--browser <A> or --browser <B>) → Debugger is not attached to the tab with id: N.
  5. Disable/disconnect profile B's extension (leave profile A connected, browser process untouched) → step 2 still fails on profile A.
  6. 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions