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
- Pass a url so a tab is created, or pass an explicit tabId.
- Call browser_open first to establish an initial tab.
- 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
- Keep one live tab during a workflow
- Pass url or tabId explicitly
- Re-open the browser after mass tab closure
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
- browser_navigate could not resolve an active tab.
- A valid browser automation session is required.
- Browser automation session tabId does not match the attached
- Browser automation session tab was not found: ${ref.tabId}
- browser_tab_activate requires tabId or session.
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/6be536a7c2e0669c.
Report an issue: GitHub.