[BUG] Claude-in-Chrome: screenshot tool permanently blocked by Next.js streaming SSR (document_idle timeout)
Bug Description
The computer tool's screenshot action always fails with "Page still loading (executeScript waited 45000ms for document_idle)" on Next.js 16 applications that use React Server Components (streaming SSR). The page is fully loaded and interactive — all other tools (javascript_tool, read_page, read_network_requests) work correctly on the same page.
Root Cause Analysis
Next.js 16 streams HTML via React Server Components. Using read_network_requests, the document request itself shows statusCode: pending even though:
document.readyState === 'complete'performance.getEntriesByType('navigation')[0].loadEventEndis set (non-zero)performance.getEntriesByType('resource')shows zero pending resources- No WebSocket connections, no pending fetches, no service workers
The extension's document_idle detection appears to check the document request's completion status at the network/CDP level, which never resolves for streaming SSR responses — even after the DOM is fully rendered and the load event has fired.
Reproduction Steps
- Create any Next.js 16 app with App Router (React Server Components are the default)
- Start the app (
next devornext build && next start— both affected) - Navigate to the app with
navigatetool - Call
computerwithaction: "screenshot"→ times out after 45 seconds - Call
javascript_toolon the same tab → works immediately,document.readyState === 'complete'
Investigation Trail
| Hypothesis | Tested | Result |
|---|---|---|
| HMR WebSocket (dev mode) | Used next build && next start (production) | Same failure |
| Service Worker (/sw.js) | Unregistered via navigator.serviceWorker.getRegistration().unregister() | Same failure |
| Pending resources | Checked performance.getEntriesByType('resource') | 0 pending |
| localhost-specific | Tried 127.0.0.1 instead | Same failure |
| Streaming SSR document | Checked read_network_requests | Document request shows statusCode: pending |
Expected Behavior
screenshot should succeed when:
document.readyState === 'complete'loadEventEnd > 0(Navigation Timing API confirms load is complete)- All sub-resources are loaded
The idle detection should not rely solely on the document request's network-level completion status, since streaming SSR intentionally keeps the HTTP response open while progressively flushing HTML — but the DOM is complete and interactive well before the stream closes.
Suggested Fix
Consider using loadEventEnd > 0 from the Navigation Timing API as the idle signal, rather than (or in addition to) the network request completion status. This correctly handles streaming SSR while maintaining the safety guarantee that the page is interactive.
Environment
- Claude Code: latest (CLI)
- Claude-in-Chrome extension: latest (Chrome Web Store)
- Chrome: latest stable
- macOS: Darwin 25.3.0 (Apple Silicon)
- Next.js: 16.2.2 (App Router, Turbopack)
- React: 19 (Server Components enabled by default)
Workaround
Use javascript_tool and read_page for page verification instead of screenshot. These tools bypass the idle check and work reliably:
javascript_tool: document.querySelectorAll('table tbody tr').length // works
read_page: filter="interactive" // works
computer: action="screenshot" // times outThis issue has 2 comments on GitHub. Read the full discussion on GitHub ↗