github/copilot-sdk · critical · RuntimeError
WebSocket response bridge is not attached
Error message
WebSocket response bridge is not attached
What it means
CopilotWebSocketRequestHandler's constructor requires the context's WebSocket response bridge to already be attached. When context._bridge is None, no bridge was wired up before creating the handler, so it cannot forward responses and raises RuntimeError immediately.
Solutions
- Attach the WebSocket response bridge to the context before constructing the handler (context._bridge = bridge)
- Use the library's standard context/factory functions so the bridge is created automatically
- Check construction order: bridge first, then CopilotWebSocketRequestHandler(context)
- Assert context._bridge is not None in your setup code to fail earlier with a clearer message
Example fix
// before handler = CopilotWebSocketRequestHandler(context) # bridge never attached // after context._bridge = WebSocketResponseBridge(...) handler = CopilotWebSocketRequestHandler(context)
Defensive patterns
Strategy: validation
Validate before calling
if context._bridge is None:
raise SetupError("attach the WebSocket response bridge before creating the handler") Type guard
def bridge_attached(context) -> bool:
return getattr(context, "_bridge", None) is not None Try / catch
try:
handler = CopilotWebSocketRequestHandler(context)
except RuntimeError as e:
if "bridge is not attached" in str(e):
context._bridge = WebSocketResponseBridge(...)
handler = CopilotWebSocketRequestHandler(context)
else:
raise Prevention
- Attach the response bridge before constructing the handler
- Use library factories instead of manual wiring
- Add a startup assertion that context._bridge is set
- Document construction order in custom server integrations
When it happens
Trigger: Constructing CopilotWebSocketRequestHandler with a CopilotRequestContext that was created without attaching a WebSocket response bridge (context._bridge is None).
Common situations: Manual wiring of the WebSocket transport where the bridge setup step was skipped or ran after handler construction, custom server integrations, or partially initialized contexts from a refactor.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- WebSocket response bridge is not attached
- WebSocket response bridge is not attached.
- Copilot request was cancelled by the runtime.
- Copilot request response used after RPC connection closed.
- Client not connected. Call start() first.
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/d1e61c70fc198581.
Report an issue: GitHub.
Appendix: source
Thrown at python/copilot/copilot_request_handler.py:137
@classmethod
def normal_closure(cls) -> CopilotWebSocketCloseStatus:
return cls()
class CopilotWebSocketHandler:
"""Per-connection WebSocket handler returned by
:meth:`CopilotRequestHandler.open_websocket`.
Subclass and override :meth:`send_request_message` (runtime → upstream) to
mutate, drop, or inject messages, and :meth:`send_response_message`
(upstream → runtime) for the reverse direction. A full transport replacement
overrides :meth:`open` to stand up its own connection and receive loop.
"""
def __init__(self, context: CopilotRequestContext) -> None:
bridge = context._bridge
if bridge is None:
raise RuntimeError("WebSocket response bridge is not attached")
self.context = context
self._response = bridge
self._completion: asyncio.Future[CopilotWebSocketCloseStatus] = (
asyncio.get_event_loop().create_future()
)
self._closed = False
self._suppress_close_on_dispose = False
async def send_response_message(self, data: str | bytes) -> None:
"""Forward an upstream message to the runtime response."""
await self._response.write(data)
async def send_request_message(self, data: str | bytes) -> None:
"""Forward a runtime message to the upstream connection. Override to mutate."""
raise NotImplementedError
async def close(self, status: CopilotWebSocketCloseStatus | None = None) -> None:
"""Initiate close: end the runtime response and resolve completion."""View on GitHub (pinned to cd8cf15dc3)