Summary
agent-browser screenshot reliably hangs and never produces a file, even though open, snapshot, wait, and eval against the same page all work. The browser clearly loads and renders (snapshot returns the correct a11y tree and the page title) — only the image-capture path fails. The daemon then becomes wedged for subsequent commands.
Environment
- agent-browser 0.27.0 (Homebrew,
/opt/homebrew/bin/agent-browser)
- macOS 26.3.1, Apple Silicon (arm64)
- Bundled browser: Chrome for Testing 149.0.7827.22 (
~/.agent-browser/browsers/chrome-149.0.7827.22), launched --headless=new --enable-unsafe-swiftshader (software GL)
Repro (trivial page — not site-specific)
$ agent-browser open https://example.com
✓ Example Domain
https://example.com/
$ agent-browser snapshot -i
- heading "Example Domain" [level=1, ref=e1]
- link "Learn more" [ref=e2]
$ agent-browser screenshot /tmp/ex.png
# (hangs, no output, no file written; never returns until killed)
Observed errors
Across attempts the screenshot fails two ways:
- On a freshly warmed session:
✗ CDP command timed out: Page.captureScreenshot
- When the daemon is already wedged from a prior hung screenshot:
✗ Failed to read: Resource temporarily unavailable (os error 35) (after 5 retries - daemon may be busy or unresponsive)
os error 35 is EAGAIN on the daemon IPC socket — i.e. the daemon is blocked (presumably awaiting the never-completing Page.captureScreenshot), so it can't service the next command either. A wedged screenshot poisons the whole session until agent-browser close --all + pkill -9 -f agent-browser-darwin.
Expected
screenshot writes a PNG (or errors quickly with an actionable message), and a failed capture must not wedge the daemon for unrelated subsequent commands.
Notes / suspicion
Page.captureScreenshot hanging while DOM/CDP is otherwise responsive points at the headless render/GPU pipeline. This machine has no hardware GL in the headless context, so Chrome runs with --enable-unsafe-swiftshader (software rasterization) — captureScreenshot may be stalling on a software-GL frame the page never flushes (e.g. PaintHolding, an offscreen surface, or compositor frame that never arrives).
- Possible mitigations worth considering: pass
--run-all-compositor-stages-before-draw / --disable-gpu / --force-color-profile=srgb to the bundled Chrome, add a hard timeout + descriptive error on Page.captureScreenshot so it fails fast instead of hanging, and ensure a capture failure releases the daemon IPC lock so the next command isn't blocked with os error 35.
Happy to provide a --verbose/CDP trace if you point me at the right flag.
Summary
agent-browser screenshotreliably hangs and never produces a file, even thoughopen,snapshot,wait, andevalagainst the same page all work. The browser clearly loads and renders (snapshot returns the correct a11y tree and the page title) — only the image-capture path fails. The daemon then becomes wedged for subsequent commands.Environment
/opt/homebrew/bin/agent-browser)~/.agent-browser/browsers/chrome-149.0.7827.22), launched--headless=new --enable-unsafe-swiftshader(software GL)Repro (trivial page — not site-specific)
Observed errors
Across attempts the screenshot fails two ways:
os error 35isEAGAINon the daemon IPC socket — i.e. the daemon is blocked (presumably awaiting the never-completingPage.captureScreenshot), so it can't service the next command either. A wedged screenshot poisons the whole session untilagent-browser close --all+pkill -9 -f agent-browser-darwin.Expected
screenshotwrites a PNG (or errors quickly with an actionable message), and a failed capture must not wedge the daemon for unrelated subsequent commands.Notes / suspicion
Page.captureScreenshothanging while DOM/CDP is otherwise responsive points at the headless render/GPU pipeline. This machine has no hardware GL in the headless context, so Chrome runs with--enable-unsafe-swiftshader(software rasterization) —captureScreenshotmay be stalling on a software-GL frame the page never flushes (e.g.PaintHolding, an offscreen surface, or compositor frame that never arrives).--run-all-compositor-stages-before-draw/--disable-gpu/--force-color-profile=srgbto the bundled Chrome, add a hard timeout + descriptive error onPage.captureScreenshotso it fails fast instead of hanging, and ensure a capture failure releases the daemon IPC lock so the next command isn't blocked withos error 35.Happy to provide a
--verbose/CDP trace if you point me at the right flag.