musistudio/claude-code-router · error · Error
browser_tab_activate requires tabId or session.
Error message
browser_tab_activate requires tabId or session.
What it means
Thrown by the browser_tab_activate MCP tool when neither args.tabId nor an attached session provides a tab identifier, and no fallback resolves. Tab activation is inherently tab-specific, so unlike browser_navigate there is no implicit 'active tab' fallback here.
Source
Thrown at packages/electron/src/main/browser-automation-mcp.ts:789
}
private async runTool(name: string, args: Record<string, unknown>): Promise<unknown> {
switch (name) {
case "browser_session_open":
return await this.openSession(args);
case "browser_session_close":
return this.closeSession(args);
case "browser_tab_create":
return await this.createTab(args);
case "browser_tab_list":
await this.ensureBrowserOpen();
return browserWindowState();
case "browser_tab_activate": {
await this.ensureBrowserOpen();
const session = this.resolveOptionalSession(args);
const tabId = readString(args.tabId) || session?.ref.tabId;
if (!tabId) {
throw new Error("browser_tab_activate requires tabId or session.");
}
const state = builtInBrowserService.selectAutomationTab(tabId);
return {
...browserWindowState(state),
tab: summarizeTab(requiredTabState(state, tabId), state.activeTabId)
};
}
case "browser_tab_close": {
await this.ensureBrowserOpen();
const session = this.resolveOptionalSession(args);
this.assertCanMutate(session);
const tabId = readString(args.tabId) || session?.ref.tabId;
if (!tabId) {
throw new Error("browser_tab_close requires tabId or session.");
}
const state = builtInBrowserService.closeAutomationTab(tabId);
this.removeSessionsForTab(tabId);
return browserWindowState(state);View on GitHub (pinned to 99f24806c6)
Solutions
- Include tabId in the tool arguments, sourced from a prior browser_open/browser_tab_list result.
- Or pass the session object returned by a previous attach/connect tool call so its ref.tabId is used.
- List tabs first (browser_tab_list) and pick a concrete id instead of relying on an implicit active tab.
Example fix
// before
await call("browser_tab_activate", {});
// after
const tabs = await call("browser_tab_list", {});
await call("browser_tab_activate", { tabId: tabs.tabs[0].id }); Defensive patterns
Strategy: validation
Validate before calling
const hasTarget = Boolean(readString(args.tabId) || args.session?.ref?.tabId);
if (!hasTarget) { const { tabs } = await call("browser_tab_list", {}); args.tabId = tabs[0]?.id; }
await call("browser_tab_activate", args); Type guard
function hasTabTarget(args: unknown): args is { tabId: string } | { session: { ref: { tabId: string } } } { const a = args as any; return typeof a?.tabId === "string" && a.tabId.trim() !== "" || typeof a?.session?.ref?.tabId === "string"; } Try / catch
try { await call("browser_tab_activate", args); } catch (e) { if (e instanceof Error && e.message.includes("requires tabId or session")) { /* fetch tabs and retry with explicit tabId */ } throw e; } Prevention
- Always pass an explicit tabId sourced from prior results
- Refresh tab ids before acting
- Don't assume implicit active-tab behavior
When it happens
Trigger: Calling tools/call with name='browser_tab_activate' and arguments containing neither tabId nor a valid session ref, after the browser has opened.
Common situations: The caller assumes the tool will target the currently active tab; the session object passed is malformed or references an expired session so session.ref.tabId is undefined.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- browser_tab_close requires tabId or session.
- A valid browser automation session is required.
- browser_chrome_login_import requires domains or an active ht
- browser_navigate could not resolve an active tab.
- Chrome login import job was not found: ${jobId}
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/366526319f356c5d.
Report an issue: GitHub.