Claude in Chrome: Page.captureScreenshot times out (30s) on any tab whose visibilityState is "hidden" (renderer backgrounded while the desktop/chat window is focused); same mechanism as #53475
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Environment
- OS: Windows
- App: Cowork desktop with the Claude Chrome extension ("Browser 1")
- Target: Gmail (mail.google.com), but the mechanism is site independent
- Onset: deterministic from approximately 2026-06-04. A screenshot-based flow that had worked for months began failing reliably.
Summary
When the Claude extension drives a Chrome tab that is not the foreground window (for example while the user is looking at the Cowork chat window), that tab reports document.visibilityState === "hidden". Chrome backgrounds the hidden renderer and stops producing compositor frames, so Page.captureScreenshot (default fromSurface: true) waits for a frame that never arrives and times out at 30000ms.
The renderer is not frozen. javascript_tool (Runtime.evaluate) against the same tab returns instantly, reads and writes the DOM, and can drive the page. Only screenshot capture is blocked.
This is the same root cause as #53475 (preview pane visibilityState permanently "hidden" when the chat pane is focused, so preview_screenshot times out), surfacing through the Claude in Chrome extension instead of the preview pane.
Evidence and prior art
- anthropics/claude-code #53475: preview pane
visibilityStatepermanently "hidden" when chat focused,preview_screenshottimes out; works when the pane is foreground. Suggested fixes:paintWhenInitiallyHidden: true,--disable-renderer-backgrounding. - ChromeDevTools/chrome-devtools-mcp #1230: frozen/discarded background tabs hang CDP page-session commands; recover via
Target.activateTarget; Chrome-side fix landing around M149. - puppeteer/puppeteer #4431: in headful mode
page.screenshotfreezes when the target page is not focused; standard remedy ispage.bringToFront()before capture.
Impact
For the Gmail send flow specifically, the extension is the only programmatic send path (the Gmail MCP connector is draft only). The documented flow located the Send button by screenshot, so the screenshot hang blocked every autonomous send while the Chrome window was backgrounded, which is the normal unattended case. The user was forced to send manually.
Workaround that works today (no screenshot)
Because the renderer is alive, the send does not need a screenshot. Dispatching a synthetic mouse-event sequence (mousedown, mouseup, click) on the Gmail Send button via javascript_tool sends the email while the tab is hidden. First verified live 2026-06-05, and since then validated continuously across six weeks of unattended scheduled sends (daily and weekly email flows), all with the Chrome window backgrounded. Note that getBoundingClientRect() returns {0,0} for compose elements while hidden, so coordinate-based clicks are not viable; event dispatch on the element is.
What Should Happen?
Suggested fix
Make the extension's screenshot path robust to hidden/backgrounded renderers, by one or more of:
- Call the equivalent of
bringToFront/Target.activateTargeton the tab beforePage.captureScreenshot, then restore focus. - Launch or configure Chrome with
--disable-renderer-backgrounding,--disable-backgrounding-occluded-windows, and--disable-features=CalculateNativeWinOcclusion, and/or setpaintWhenInitiallyHiddenfor driven tabs (the fixes proposed in #53475). - Classify a
captureScreenshottimeout on a tab whosevisibilityStateis "hidden" as a recoverable, actionable error rather than "the renderer may be frozen", since the renderer is in fact responsive.
Error Messages/Logs
Steps to Reproduce
- Connect the Claude extension to Chrome and leave the Chrome window in the background (focus the Cowork desktop app or any other window).
- Drive a tab via the extension (open a page, or a Gmail draft).
- Call the screenshot tool on that tab.
Expected: a screenshot. Actual: CDP sendCommand "Page.captureScreenshot" timed out after 30000ms ... The renderer may be frozen or unresponsive.
Confirming probe: on the same hung tab, javascript_tool returns { visibilityState: "hidden", readyState: "complete" } instantly, proving the renderer is alive.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude Code v2.1.212
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
_No response_