{"record":{"id":"366526319f356c5d","repo":"musistudio/claude-code-router","slug":"browser-tab-activate-requires-tabid-or-session","errorCode":null,"errorMessage":"browser_tab_activate requires tabId or session.","messagePattern":"browser_tab_activate requires tabId or session\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/electron/src/main/browser-automation-mcp.ts","lineNumber":789,"sourceCode":"  }\n\n  private async runTool(name: string, args: Record<string, unknown>): Promise<unknown> {\n    switch (name) {\n      case \"browser_session_open\":\n        return await this.openSession(args);\n      case \"browser_session_close\":\n        return this.closeSession(args);\n      case \"browser_tab_create\":\n        return await this.createTab(args);\n      case \"browser_tab_list\":\n        await this.ensureBrowserOpen();\n        return browserWindowState();\n      case \"browser_tab_activate\": {\n        await this.ensureBrowserOpen();\n        const session = this.resolveOptionalSession(args);\n        const tabId = readString(args.tabId) || session?.ref.tabId;\n        if (!tabId) {\n          throw new Error(\"browser_tab_activate requires tabId or session.\");\n        }\n        const state = builtInBrowserService.selectAutomationTab(tabId);\n        return {\n          ...browserWindowState(state),\n          tab: summarizeTab(requiredTabState(state, tabId), state.activeTabId)\n        };\n      }\n      case \"browser_tab_close\": {\n        await this.ensureBrowserOpen();\n        const session = this.resolveOptionalSession(args);\n        this.assertCanMutate(session);\n        const tabId = readString(args.tabId) || session?.ref.tabId;\n        if (!tabId) {\n          throw new Error(\"browser_tab_close requires tabId or session.\");\n        }\n        const state = builtInBrowserService.closeAutomationTab(tabId);\n        this.removeSessionsForTab(tabId);\n        return browserWindowState(state);","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/electron/src/main/browser-automation-mcp.ts#L771-L807","documentation":"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.","triggerScenarios":"Calling tools/call with name='browser_tab_activate' and arguments containing neither tabId nor a valid session ref, after the browser has opened.","commonSituations":"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.","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."],"exampleFix":"// before\nawait call(\"browser_tab_activate\", {});\n\n// after\nconst tabs = await call(\"browser_tab_list\", {});\nawait call(\"browser_tab_activate\", { tabId: tabs.tabs[0].id });","handlingStrategy":"validation","validationCode":"const hasTarget = Boolean(readString(args.tabId) || args.session?.ref?.tabId);\nif (!hasTarget) { const { tabs } = await call(\"browser_tab_list\", {}); args.tabId = tabs[0]?.id; }\nawait call(\"browser_tab_activate\", args);","typeGuard":"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\"; }","tryCatchPattern":"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; }","preventionTips":["Always pass an explicit tabId sourced from prior results","Refresh tab ids before acting","Don't assume implicit active-tab behavior"],"tags":["mcp","browser-automation","missing-param","tab-management"],"backgroundTag":"missing-required-parameter","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}