browser-use/browser-use · error · TimeoutError

CDP method {method!r} did not respond within {self._cdp_requ

Error message

CDP method {method!r} did not respond within {self._cdp_request_timeout_s:.0f}s. The browser may be unresponsive (silent WebSocket — container crashed or proxy lost upstream).

What it means

A CDPConnection wrapper enforces a per-request timeout (`_cdp_request_timeout_s`) around every raw CDP WebSocket send. When a method (e.g. Page.navigate, Runtime.evaluate) gets no response frame within the window, it raises TimeoutError with the method name and a hint: the WebSocket stayed open but silent, typical of a crashed browser container or a proxy that lost its upstream connection. It deliberately raises plain TimeoutError so existing handlers match uniformly.

Source

Thrown at browser_use/browser/_cdp_timeout.py:122

	) -> None:
		super().__init__(*args, **kwargs)
		self._cdp_request_timeout_s: float = _coerce_valid_timeout(cdp_request_timeout_s)

	async def send_raw(
		self,
		method: str,
		params: Any | None = None,
		session_id: str | None = None,
	) -> dict[str, Any]:
		try:
			return await asyncio.wait_for(
				super().send_raw(method=method, params=params, session_id=session_id),
				timeout=self._cdp_request_timeout_s,
			)
		except TimeoutError as e:
			# Raise a plain TimeoutError so existing `except TimeoutError`
			# handlers in browser-use / tools treat this uniformly.
			raise TimeoutError(
				f'CDP method {method!r} did not respond within {self._cdp_request_timeout_s:.0f}s. '
				f'The browser may be unresponsive (silent WebSocket — container crashed or proxy lost upstream).'
			) from e

View on GitHub (pinned to 6c73fced2f)

Solutions

  1. Treat it as a dead browser: tear down the session (`await browser.close()`) and recreate it, then retry the task — a hung CDP socket rarely recovers.
  2. If genuinely slow operations are expected, raise `_cdp_request_timeout_s` on the CDP connection config.
  3. For containers: add memory/CPU headroom or a Chrome watchdog to stop silent OOM kills.
  4. For `cdp_url` setups: verify the proxy/upstream health independently before blaming the page.

Example fix

# before
state = await agent.run()  # mid-run CDP hang surfaces as TimeoutError, run keeps waiting

# after
import asyncio
from browser_use import Agent, Browser
async def main():
    try:
        return await Agent(task=t, llm=llm, browser=Browser()).run(max_steps=20)
    except TimeoutError:
        await browser.close()  # kill dead session
        return await Agent(task=t, llm=llm, browser=Browser()).run(max_steps=20)  # fresh retry
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight: cheap CDP round-trip before launching a long task
async def cdp_alive(browser, timeout_s=10) -> bool:
    try:
        conn = await browser._get_cdp_connection() if hasattr(browser, '_get_cdp_connection') else None
        if conn is None:
            return True  # cannot probe; assume ok
        await asyncio.wait_for(conn.send_raw('Browser.getVersion'), timeout=timeout_s)
        return True
    except TimeoutError:
        return False

Try / catch

async def run_resilient(task, llm, max_restarts=2):
    for attempt in range(max_restarts + 1):
        browser = Browser()
        try:
            agent = Agent(task=task, llm=llm, browser=browser)
            return await agent.run()
        except TimeoutError as e:
            if 'CDP method' not in str(e) or attempt == max_restarts:
                raise
            logger.warning('CDP hang (%s); recreating browser', e)
        finally:
            await browser.close()

Prevention

When it happens

Trigger: Any CDP operation while the browser process is hung or dead-but-socket-open: OOM-killed headless Chrome in Docker, a remote browser behind a proxy whose upstream dropped, frozen page due to GPU/render deadlock, or an extremely slow method exceeding the configured timeout.

Common situations: Long-running automation in containers where Chrome gets OOM-reaped; remote/CDP-URL setups (`cdp_url=`) through flaky proxies; heavy pages (infinite loops in JS) blocking the CDP response thread; timeouts surfacing after network changes mid-session.

Understand the failure class

Related errors


AI-assisted analysis of browser-use/browser-use@6c73fced2f (2026-08-14). Data as JSON: /api/errors/dfbd33df757a50c6. Report an issue: GitHub.