xtekky/gpt4free · error · RuntimeError
CDPSession is not connected
Error message
CDPSession is not connected
What it means
Raised by CDPSession.call() in g4f/requests/cdp.py when self.ws is falsy — i.e. a CDP command is issued before connect()/start() completed, or after close() tore down the WebSocket. The session object exists but has no live debugger socket, so any protocol call is refused immediately.
Source
Thrown at g4f/requests/cdp.py:433
# Resolve any futures waiting for this event
if method in self._event_handlers:
for fut in self._event_handlers[method]:
if not fut.done():
fut.set_result(params)
self._event_handlers[method].clear()
if method in self._event_queues:
for q in self._event_queues[method]:
q.put_nowait(params)
except Exception as e:
if not self._closing:
logger.error(f"CDP receiver loop error: {e}")
async def call(self, method: str, **params) -> dict:
"""Call a CDP method and wait for its result."""
if not self.ws:
raise RuntimeError("CDPSession is not connected")
self.id_counter += 1
req_id = self.id_counter
fut = asyncio.get_running_loop().create_future()
self._pending_requests[req_id] = fut
payload = {"id": req_id, "method": method, "params": params}
await self.ws.send_json(payload)
try:
return await asyncio.wait_for(fut, timeout=30.0)
except asyncio.TimeoutError:
raise TimeoutError(f"CDP call {method} timed out after 30 seconds")
finally:
self._pending_requests.pop(req_id, None)
async def wait_for_event(self, method: str, timeout: float = 30.0) -> dict:View on GitHub (pinned to 973504e177)
Solutions
- Ensure the session lifecycle is correct: await session.start() before any call, and stop issuing calls after close().
- Check `session.ws is not None` (or track a connected flag) before invoking call() from shared code paths.
- If another task may close concurrently, guard calls with an asyncio.Lock or check `session._closing`.
- Create a fresh CDPSession after a close instead of reusing the old object.
Example fix
// before
session = CDPSession()
await session.call("Page.enable") # ws is None -> RuntimeError
// after
session = CDPSession()
await session.start()
try:
await session.call("Page.enable")
finally:
await session.close() Defensive patterns
Strategy: type-guard
Validate before calling
if session.ws is None:
raise RuntimeError("Connect the session first: await session.start()") Type guard
def is_connected(session) -> bool:
"""True when the CDPSession has a live debugger socket."""
return getattr(session, "ws", None) is not None and not getattr(session, "_closing", False) Try / catch
try:
result = await session.call(method, **params)
except RuntimeError as e:
if "not connected" in str(e):
session = CDPSession(); await session.start() # reconnect and retry once
result = await session.call(method, **params)
else:
raise Prevention
- Always pair start()/close() with try/finally so the session is never used after teardown.
- Check session.ws before calls in shared/multi-task code paths.
- Never reuse a CDPSession after close(); create a fresh one.
When it happens
Trigger: Calling session.call("Page.navigate", ...) without awaiting session.start() first; using the session inside an except/finally block after close() already ran; reusing a session whose receiver loop crashed and closed the socket.
Common situations: Missing await in asyncio code (start() never awaited); sharing one session across tasks where one task closes it while another still sends commands; forgetting that close() invalidates the object permanently.
Related errors
- Timeout waiting for event {method}
- Install "nest-asyncio2" package | pip install -U nest-asynci
- The operation timed out after {} seconds
- The operation timed out after {} seconds
- The operation timed out after {} seconds in {}
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/e9203943614a68c7.
Report an issue: GitHub.