Browser Use IAB should classify recoverable CDP command timeouts instead of cleanup-and-rethrow

Open 💬 3 comments Opened May 7, 2026 by scottfalconer

What version of the Codex App are you using (From “About Codex” dialog)?

26.429.61741

What subscription do you have?

ChatGPT Pro

What platform is your computer?

macOS / Darwin arm64

  • OS kernel: Darwin 24.5.0 RELEASE_ARM64_T6000 arm64
  • Codex app: CFBundleShortVersionString=26.429.61741, CFBundleVersion=2429
  • Browser Use plugin: browser-use 0.1.0-alpha1
  • Browser Use backend: iab
  • Session meta CLI version: 0.128.0-alpha.1
  • Current shell CLI version: codex-cli 0.128.0

What issue are you seeing?

Browser Use IAB surfaced an intermittent timeout from a safe visual-read command:

Timed out running CDP command "Page.captureScreenshot" for tab 1

The observed user-facing failure happened during:

await display(await tab.playwright.screenshot({ fullPage: false }));

The failure occurred before display(...) received image bytes. The raw tool result named CDP Page.captureScreenshot, with elapsed wall time around 20.0s even though the surrounding Node REPL tool call had timeout_ms: 30000.

This was not a deterministic page-rendering failure:

  • Immediately before the screenshot call, title/URL/console inspection worked.
  • Immediately after the screenshot timeout, tab.playwright.domSnapshot() succeeded on the same Browser Use tab.
  • Later recovery testing in a fresh Browser Use session succeeded for the same URL/tab shape:
  • same tab screenshot: ~87 ms
  • same tab after reload: ~60 ms
  • fresh Browser Use tab: ~60 ms
  • repeated screenshot calls later succeeded around ~40-44 ms
  • No browser console warnings/errors were observed for the page.

So the narrower symptom is "screenshot timed out," but the more fundamental issue appears to be that Browser Use IAB treats CDP command timeouts as generic cleanup-and-rethrow failures rather than classifying whether the command is recoverable or safe to retry.

What steps can reproduce the bug?

I do not currently have a deterministic repro. The original failure was captured in a real Codex Desktop Browser Use session while the in-app browser had a local page open:

http://127.0.0.1:8776/live-map.html?outing=1-2

Exact failing command from the session log:

await display(await tab.playwright.screenshot({ fullPage: false }));

Exact error returned by the Browser Use call:

Timed out running CDP command "Page.captureScreenshot" for tab 1

The command duration in the raw log was approximately 20.026 seconds.

What is the expected behavior?

Browser Use IAB should not treat every CDP command timeout the same way.

For safe/idempotent visual-read commands such as Page.captureScreenshot and likely nearby layout/DOM read commands, IAB should be able to classify the timeout as recoverable, detach/reattach if needed, and retry once or otherwise surface a structured recoverable error that guides the caller to retry.

It should not blindly retry side-effecting commands such as input, click, navigation, close, or reload commands where duplication could be harmful.

What is the actual behavior?

The observed screenshot call failed with a plain timeout error. The agent did not receive screenshot bytes, and the failure appeared terminal even though the same tab continued to respond to other Browser Use commands immediately afterward.

Code inspection of the bundled Desktop/IAB path suggests this is expected from the current implementation:

  • The Browser Use JS screenshot helper calls Page.getLayoutMetrics, then Page.captureScreenshot.
  • cua_get_visible_screenshot also calls Page.captureScreenshot directly.
  • The Codex Desktop IAB backend wraps ordinary webContents.debugger.sendCommand(...) calls with a default 20s timeout.
  • On any error whose message starts with Timed out, the IAB backend calls debugger cleanup with reason cdp-timeout, then rethrows the original timeout.
  • There does not appear to be retry/backoff or method-aware recoverability classification around this path.

The same code area already has command-specific handling for other cases:

  • Page.reload bypasses raw CDP and uses Electron reload APIs.
  • Input.* commands are translated to JavaScript because input handling has IAB-specific focus/safety constraints.
  • Page.close has explicit cleanup behavior.
  • initial page load and navigation-history lookup have separate timeout messages/paths.

That suggests the missing abstraction is not screenshot-specific; it is a method-aware CDP timeout policy for IAB.

Additional information

This is intentionally filed as an evidence-supported intermittent Browser Use/IAB robustness issue, not as a deterministic page bug.

Potential fix direction:

  • Introduce a small CDP timeout classification layer in the IAB backend.
  • Mark safe read/capture commands as retryable after cleanup/reattach, with a low retry count such as one attempt.
  • Keep input/navigation/close/reload commands non-retryable unless they have explicit command-specific recovery semantics.
  • Return structured error metadata when a timeout was cleaned up and the tab/browser may still be usable.

This would make the observed Page.captureScreenshot failure recover better while avoiding unsafe duplicate interactions.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗