{"record":{"id":"d1e61c70fc198581","repo":"github/copilot-sdk","slug":"websocket-response-bridge-is-not-attached-d1e61c","errorCode":null,"errorMessage":"WebSocket response bridge is not attached","messagePattern":"WebSocket response bridge is not attached","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"python/copilot/copilot_request_handler.py","lineNumber":137,"sourceCode":"    @classmethod\n    def normal_closure(cls) -> CopilotWebSocketCloseStatus:\n        return cls()\n\n\nclass CopilotWebSocketHandler:\n    \"\"\"Per-connection WebSocket handler returned by\n    :meth:`CopilotRequestHandler.open_websocket`.\n\n    Subclass and override :meth:`send_request_message` (runtime → upstream) to\n    mutate, drop, or inject messages, and :meth:`send_response_message`\n    (upstream → runtime) for the reverse direction. A full transport replacement\n    overrides :meth:`open` to stand up its own connection and receive loop.\n    \"\"\"\n\n    def __init__(self, context: CopilotRequestContext) -> None:\n        bridge = context._bridge\n        if bridge is None:\n            raise RuntimeError(\"WebSocket response bridge is not attached\")\n        self.context = context\n        self._response = bridge\n        self._completion: asyncio.Future[CopilotWebSocketCloseStatus] = (\n            asyncio.get_event_loop().create_future()\n        )\n        self._closed = False\n        self._suppress_close_on_dispose = False\n\n    async def send_response_message(self, data: str | bytes) -> None:\n        \"\"\"Forward an upstream message to the runtime response.\"\"\"\n        await self._response.write(data)\n\n    async def send_request_message(self, data: str | bytes) -> None:\n        \"\"\"Forward a runtime message to the upstream connection. Override to mutate.\"\"\"\n        raise NotImplementedError\n\n    async def close(self, status: CopilotWebSocketCloseStatus | None = None) -> None:\n        \"\"\"Initiate close: end the runtime response and resolve completion.\"\"\"","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/python/copilot/copilot_request_handler.py#L119-L155","documentation":"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.","triggerScenarios":"Constructing CopilotWebSocketRequestHandler with a CopilotRequestContext that was created without attaching a WebSocket response bridge (context._bridge is None).","commonSituations":"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.","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"],"exampleFix":"// before\nhandler = CopilotWebSocketRequestHandler(context)  # bridge never attached\n// after\ncontext._bridge = WebSocketResponseBridge(...)\nhandler = CopilotWebSocketRequestHandler(context)","handlingStrategy":"validation","validationCode":"if context._bridge is None:\n    raise SetupError(\"attach the WebSocket response bridge before creating the handler\")","typeGuard":"def bridge_attached(context) -> bool:\n    return getattr(context, \"_bridge\", None) is not None","tryCatchPattern":"try:\n    handler = CopilotWebSocketRequestHandler(context)\nexcept RuntimeError as e:\n    if \"bridge is not attached\" in str(e):\n        context._bridge = WebSocketResponseBridge(...)\n        handler = CopilotWebSocketRequestHandler(context)\n    else:\n        raise","preventionTips":["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"],"tags":["websocket","initialization","bridge","wiring"],"backgroundTag":"internal-invariant-violation","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}