musistudio/claude-code-router · error · Error

Unable to resolve browser tab for automation session.

Error message

Unable to resolve browser tab for automation session.

What it means

Thrown after tab-resolution logic in the main automation tool run when tabId is still falsy — no explicit tabId was given, no url was supplied that would trigger tab creation, and there is no active tab to reuse. It guards the invariant that a run must be bound to a tab before touching webContents.

Source

Thrown at packages/electron/src/main/browser-automation-mcp.ts:1132

    let createdTab = false;

    if (tabId && !state.tabs.some((tab) => tab.id === tabId)) {
      throw new Error(`Browser tab was not found: ${tabId}`);
    }

    if (!tabId && url) {
      const tab = builtInBrowserService.createAutomationTab();
      tabId = tab.id;
      createdTab = true;
    } else if (!tabId) {
      tabId = state.activeTabId || builtInBrowserService.createAutomationTab().id;
      createdTab = !state.activeTabId;
    } else if (state.activeTabId !== tabId) {
      builtInBrowserService.selectAutomationTab(tabId);
    }

    if (!tabId) {
      throw new Error("Unable to resolve browser tab for automation session.");
    }

    const waitUntil = normalizeWaitUntil(readString(args.waitUntil), url ? "interactive" : "none");
    const timeoutMs = clampInteger(readNumber(args.timeoutMs) ?? defaultWaitTimeoutMs, 100, 120000);
    const webContents = builtInBrowserService.getAutomationWebContents(tabId);
    const readiness = await waitForReadiness(
      webContents,
      waitUntil,
      timeoutMs,
      url ? () => builtInBrowserService.navigateAutomationTab(url, tabId) : undefined,
      url
    );
    state = builtInBrowserService.getAutomationState();
    const tab = requiredTabState(state, tabId);
    const ref: BrowserSessionRef = {
      sessionId: randomUUID(),
      tabId,
      ...(readString(args.userId) ? { userId: readString(args.userId) } : {})

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Pass a url so a tab is created, or pass an explicit tabId.
  2. Call browser_open first to establish an initial tab.
  3. Keep at least one tab open in automation scripts, or re-attach after closing tabs.

Example fix

// before
await call("browser_snapshot", {}); // no tabId, no active tab

// after
await call("browser_open", { url: "https://example.com" });
await call("browser_snapshot", {});
Defensive patterns

Strategy: fallback

Validate before calling

const state = await call("browser_tab_list", {});
if (!state.tabs.length) await call("browser_open", { url: "https://example.com" });
await call("browser_snapshot", {});

Try / catch

try { await call(toolName, args); } catch (e) { if (e instanceof Error && e.message.includes("Unable to resolve browser tab")) { await call("browser_open", { url }); await call(toolName, args); } else throw e; }

Prevention

When it happens

Trigger: Calling an automation tool with neither tabId nor url on a browser whose activeTabId is null (e.g. after closing all tabs), so no creation or fallback path applies.

Common situations: Calling a snapshot/screenshot-style tool with no arguments when the hidden automation browser has zero tabs; a script step that only passes a session ref whose tab vanished.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/6be536a7c2e0669c. Report an issue: GitHub.