Skip to content

fix(cdp): prevent indefinite hangs on remote browsers via DOMWatchdog timeouts#4875

Open
Parth-001-git wants to merge 1 commit into
browser-use:mainfrom
Parth-001-git:fix/issue-4579-dom-watchdog-cdp-timeouts
Open

fix(cdp): prevent indefinite hangs on remote browsers via DOMWatchdog timeouts#4875
Parth-001-git wants to merge 1 commit into
browser-use:mainfrom
Parth-001-git:fix/issue-4579-dom-watchdog-cdp-timeouts

Conversation

@Parth-001-git

@Parth-001-git Parth-001-git commented May 20, 2026

Copy link
Copy Markdown

So I tracked down the hang issue around remote CDP sessions getting stuck indefinitely when the websocket silently degrades in Docker/cloud setups.

The main problem was that a few DOMWatchdog calls were awaiting CDP responses forever with no timeout boundaries, so once the socket went half-open the event bus lock never got released and parallel browser sessions just piled up behind it.

What's working now:

  • Added timeout guards around the main CDP execute paths
  • Mark degraded sessions unhealthy automatically
  • Added lightweight connection health verification before watchdog execution
  • Prevented the watchdog from blocking the whole event loop indefinitely

One annoying thing I hit while testing was reproducing the half-open websocket state consistently. Local runs were fine because TCP teardown happens immediately on localhost. Ended up simulating packet drops inside Docker/WSL to reproduce the actual hanging behavior reliably.

Also hit a small WSL issue with pre-commit expecting python3.11 specifically, but that was just local env noise — ruff + formatting + targeted tests are all passing.

Core fix looks like this now:

result = await asyncio.wait_for(
    cdp_session.execute(
        Runtime.evaluate(
            expression="window.performance.getEntriesByType('resource')",
            await_promise=True
        )
    ),
    timeout=5.0,  # remote CDP calls shouldn't block forever
)

except asyncio.TimeoutError:
    logger.warning("CDP session timed out while fetching network requests")

    # connection probably went half-open behind proxy/load balancer
    self.browser_session._is_healthy = False

    raise ConnectionError(
        "Remote browser connection became unresponsive"
    )

I also added tests around timeout handling + connection health verification so we don't regress on this later.


Summary by cubic

Prevents remote CDP sessions from hanging by adding bounded timeouts and proactive health checks, so half‑open WebSockets in Docker/cloud no longer stall the event loop. Parallel sessions now recover or fail fast. Fixes #4579.

  • Bug Fixes
    • Added _is_healthy flag that gates is_cdp_connected, plus verify_connection_health() (1.5s Browser.getVersion ping).
    • Watchdog circuit breaker verifies health before handler runs; on failure marks unhealthy and auto‑reconnects, or skips if the browser was intentionally stopped.
    • Bounded timeouts for key CDP/DOM paths (e.g., 5s around get_or_create_cdp_session, network request checks, DOM build, screenshot); on timeout mark session unhealthy and raise ConnectionError.
    • Tests in tests/ci/test_connection_health.py cover health flag lifecycle, ping success/timeout, and DOMWatchdog timeout handling.

Written for commit 4bc538d. Summary will update on new commits. Review in cubic

@CLAassistant

CLAassistant commented May 20, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Re-trigger cubic

@Parth-001-git

Copy link
Copy Markdown
Author

Hey, I dug into #4579 around remote CDP sessions hanging indefinitely on degraded websocket connections.

The main issue seemed to be that several DOMWatchdog CDP calls were awaiting without timeout boundaries, so once a remote connection went half-open the watchdog could block the event bus and stall parallel sessions.

I pushed a fix that:

  • wraps the critical CDP execute paths with asyncio.wait_for
  • marks degraded sessions unhealthy on timeout
  • adds lightweight connection health verification before watchdog execution

Also added tests around timeout handling + connection recovery flow.

Would appreciate feedback on the timeout/reconnect strategy, especially around whether you'd prefer more aggressive session invalidation or softer recovery behavior for pooled remote browsers.

@sauravpanda

Copy link
Copy Markdown
Collaborator

this is awesome, can you remove unrelated changes to your PR like spacing and stuff, doesnt make sense.

@Parth-001-git

Copy link
Copy Markdown
Author

Yeah, some extra formatting changes slipped in locally. I’ll clean the diff up and keep it scoped to the timeout/recovery fix.

… timeouts

- Add _is_healthy flag to BrowserSession for connection state tracking
- Add verify_connection_health() lightweight CDP ping (1.5s timeout)
- Guard is_cdp_connected with _is_healthy check
- Wrap _get_pending_network_requests CDP call in asyncio.wait_for (5s)
- Add TimeoutError catch blocks to 3 critical DOMWatchdog methods
- On timeout: log, mark session unhealthy, raise ConnectionError
- Add proactive health check in watchdog event handler circuit breaker
- Trigger auto-reconnect when health check fails
- Add 4 targeted tests for health verification and timeout handling

Fixes browser-use#4579
@Parth-001-git Parth-001-git force-pushed the fix/issue-4579-dom-watchdog-cdp-timeouts branch from 3e0b578 to 4bc538d Compare May 21, 2026 01:40
@Parth-001-git

Copy link
Copy Markdown
Author

Cleaned up the unrelated formatting changes and kept the diff scoped to the timeout/recovery logic + tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: CDP connection instability causing indefinite hangs with remote browsers

3 participants