{"record":{"id":"81928001fb266d3d","repo":"xtekky/gpt4free","slug":"cdp-call-method-timed-out-after-30-seconds","errorCode":null,"errorMessage":"CDP call {method} timed out after 30 seconds","messagePattern":"CDP call (.+?) timed out after 30 seconds","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"g4f/requests/cdp.py","lineNumber":447,"sourceCode":"\n    async def call(self, method: str, **params) -> dict:\n        \"\"\"Call a CDP method and wait for its result.\"\"\"\n        if not self.ws:\n            raise RuntimeError(\"CDPSession is not connected\")\n\n        self.id_counter += 1\n        req_id = self.id_counter\n\n        fut = asyncio.get_running_loop().create_future()\n        self._pending_requests[req_id] = fut\n\n        payload = {\"id\": req_id, \"method\": method, \"params\": params}\n        await self.ws.send_json(payload)\n\n        try:\n            return await asyncio.wait_for(fut, timeout=30.0)\n        except asyncio.TimeoutError:\n            raise TimeoutError(f\"CDP call {method} timed out after 30 seconds\")\n        finally:\n            self._pending_requests.pop(req_id, None)\n\n    async def wait_for_event(self, method: str, timeout: float = 30.0) -> dict:\n        \"\"\"Wait for a specific CDP event to fire (one-time).\"\"\"\n        fut = asyncio.get_running_loop().create_future()\n        if method not in self._event_handlers:\n            self._event_handlers[method] = []\n        self._event_handlers[method].append(fut)\n\n        try:\n            return await asyncio.wait_for(fut, timeout=timeout)\n        except asyncio.TimeoutError:\n            self._event_handlers[method].remove(fut)\n            raise TimeoutError(f\"Timeout waiting for event {method}\")\n\n    def add_event_handler(self, method: str, queue: asyncio.Queue):\n        \"\"\"Add a persistent event listener that pushes events to an asyncio.Queue.\"\"\"","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/requests/cdp.py#L429-L465","documentation":"Raised by CDPSession.call() in g4f/requests/cdp.py when the CDP command was sent over the WebSocket but no matching response (by request id) arrived within a hard-coded 30 second asyncio.wait_for. The pending future is cleaned up in finally, and the TimeoutError surfaces with the method name. Typical causes are a hung renderer, a dead-but-not-closed socket, or a genuinely slow command like a navigation that never finishes.","triggerScenarios":"Calling Page.navigate to a page that never fires load; Runtime.evaluate on a script with an infinite loop; the browser process froze (OOM, GPU hang); the WebSocket dropped silently so responses never arrive.","commonSituations":"Heavy pages under memory pressure; sandboxed containers with limited CPU so Chrome is starved; long-running Turnstile/Cloudflare challenges exceeding 30s; network flakiness between client and a remote-hosted Chrome.","solutions":["Retry the call once — transient browser hiccups often clear.","If it reproduces on a specific navigate/evaluate, test that page manually in the same Chrome to find what hangs (infinite loop, blocking dialog, unreachable subresource).","Restart the shared browser process (kill chrome / let g4f's lock logic recycle it) to recover a frozen instance.","Give the container more CPU/memory; a starved Chrome routinely misses 30s deadlines.","Split very long operations: navigate with a shorter expectation, then poll via evaluate_js instead of one 30s+ call."],"exampleFix":"// before\nresult = await session.call(\"Page.navigate\", url=slow_page)  # may exceed 30s\n\n// after\nfor attempt in range(3):\n    try:\n        result = await session.call(\"Page.navigate\", url=slow_page)\n        break\n    except TimeoutError:\n        if attempt == 2:\n            raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = await session.call(\"Page.navigate\", url=url)\nexcept TimeoutError as e:\n    log.warning(f\"{e}; restarting browser and retrying once\")\n    await restart_browser()\n    result = await session.call(\"Page.navigate\", url=url)","preventionTips":["Keep individual CDP operations short; poll state instead of one long call.","Monitor chrome process health (memory/CPU) in long-running services and recycle proactively.","Budget container resources so Chrome is not starved past the hard-coded 30s."],"tags":["cdp","timeout","websocket","retryable","performance"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}