{"record":{"id":"431c0174da5d1ce1","repo":"can1357/oh-my-pi","slug":"the-attached-browser-tab-is-not-visible-switch-to","errorCode":null,"errorMessage":"The attached browser tab is not visible; switch to it before taking a screenshot","messagePattern":"The attached browser tab is not visible; switch to it before taking a screenshot","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/browser/tab-worker.ts","lineNumber":944,"sourceCode":"export function describeScreenshot(opts?: ScreenshotOptions): string {\n\tif (opts?.selector) return `tab.screenshot({ selector: ${JSON.stringify(opts.selector)} })`;\n\tif (opts?.fullPage) return \"tab.screenshot({ fullPage: true })\";\n\treturn \"tab.screenshot()\";\n}\nexport async function preparePageForScreenshot(\n\tpage: Pick<Page, \"bringToFront\" | \"evaluate\">,\n\tsignal: AbortSignal | undefined,\n\tactivate: boolean,\n): Promise<void> {\n\tif (activate) {\n\t\tawait untilAborted(signal, () => page.bringToFront()).catch(() => undefined);\n\t\treturn;\n\t}\n\tconst visible = await untilAborted(signal, () => page.evaluate(() => document.visibilityState === \"visible\")).catch(\n\t\t() => false,\n\t);\n\tif (!visible) {\n\t\tthrow new ToolError(\"The attached browser tab is not visible; switch to it before taking a screenshot\");\n\t}\n}\n\n/** Summarize still-running helpers (oldest first) so a cell timeout names what stalled. */\nexport function describeInflight(inflight: Map<number, InflightOp>): string {\n\tconst now = Date.now();\n\treturn [...inflight.values()]\n\t\t.sort((a, b) => a.startedAt - b.startedAt)\n\t\t.map(op => `${op.label} (${((now - op.startedAt) / 1000).toFixed(1)}s)`)\n\t\t.join(\", \");\n}\n\nexport class WorkerCore {\n\t#transport: Transport;\n\t#browser?: Browser;\n\t#page?: Page;\n\t#targetId?: string;\n\t#elementCache = new Map<number, ElementHandle>();","sourceCodeStart":926,"sourceCodeEnd":962,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/browser/tab-worker.ts#L926-L962","documentation":"Before taking a screenshot of an attached (user-visible) browser tab, the worker checks `document.visibilityState === \"visible\"` in the page. Attached tabs can be hidden (background tab, minimized window, occluded); screenshots of hidden tabs would be blank, so the tool throws and asks the user to switch to the tab first.","triggerScenarios":"Calling screenshot on a tab attached to the user's real browser while that tab is in a background tab, a minimized window, or otherwise not the active tab — `visibilityState` is `hidden`.","commonSituations":"User opened the automated tab then switched away mid-run; OS-level window minimization; multi-window setups where the tool operates on a non-focused window.","solutions":["Switch to the target tab (bring its window to front / activate the tab) and retry the screenshot.","Run the browser headless instead of attaching to a visible browser — headless pages report `visible`.","Structure the workflow to minimize tab switching, or notify the user to keep the tab focused during screenshots.","Handle the error in the automation by using snapshot/observe (DOM-based) instead of a pixel screenshot when the tab can't be focused."],"exampleFix":"// before\nawait tab.screenshot(); // tab is in background\n// after\nawait tab.activate(); // bring tab to front\nawait tab.screenshot();","handlingStrategy":"fallback","validationCode":"const visible = await page.evaluate(() => document.visibilityState === \"visible\").catch(() => false);\nif (!visible) await tab.activate(); // bring tab to front first","typeGuard":null,"tryCatchPattern":"try {\n  await tab.screenshot();\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"not visible\")) {\n    return tab.ariaSnapshot(); // DOM-based fallback when focus can't be given\n  }\n  throw err;\n}","preventionTips":["Activate the tab before screenshots of attached browsers","Prefer headless mode when pixel output is needed and focus can't be guaranteed","Use ariaSnapshot/observe instead of screenshots when the tab may be backgrounded"],"tags":["screenshot","visibility","attached-browser","browser-tool"],"backgroundTag":"tab-not-visible-screenshot","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}