{"record":{"id":"b6db96c8c4ac6bb9","repo":"openai/openai-python","slug":"websocket-connection-closed-with-unsent-messages","errorCode":null,"errorMessage":"WebSocket connection closed with unsent messages","messagePattern":"WebSocket connection closed with unsent messages","errorType":"error_code","errorClass":"WebSocketConnectionClosedError","httpStatus":null,"severity":"error","filePath":"src/openai/resources/beta/responses/responses.py","lineNumber":4155,"sourceCode":"        self.response = AsyncResponsesResponseResource(self)\n\n    async def __aiter__(self) -> AsyncIterator[BetaResponsesServerEvent]:\n        \"\"\"\n        An infinite-iterator that will continue to yield events until\n        the connection is closed.\n        \"\"\"\n        from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError\n\n        while True:\n            try:\n                yield await self.recv()\n            except ConnectionClosedOK:\n                return\n            except ConnectionClosedError as exc:\n                if not await self._reconnect(exc):\n                    unsent = self._send_queue.drain()\n                    if unsent:\n                        raise WebSocketConnectionClosedError(\n                            \"WebSocket connection closed with unsent messages\",\n                            unsent_messages=unsent,\n                        ) from exc\n                    raise\n\n    async def recv(self) -> BetaResponsesServerEvent:\n        \"\"\"\n        Receive the next message from the connection and parses it into a `BetaResponsesServerEvent` object.\n\n        Canceling this method is safe. There's no risk of losing data.\n        \"\"\"\n        return self.parse_event(await self.recv_bytes())\n\n    async def recv_bytes(self) -> bytes:\n        \"\"\"Receive the next message from the connection as raw bytes.\n\n        Canceling this method is safe. There's no risk of losing data.\n","sourceCodeStart":4137,"sourceCodeEnd":4173,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/resources/beta/responses/responses.py#L4137-L4173","documentation":"When iterating the async WebSocket response stream, the connection closed with an error and reconnection failed while messages were still queued for sending. The SDK drains the send queue and raises WebSocketConnectionClosedError with the unsent messages attached so no outbound data is silently lost. This only fires for abnormal closures (ConnectionClosedError), not clean closes.","triggerScenarios":"Calling send() on the async BetaResponses WebSocket connection and then consuming with async for, when the socket drops (network failure, server-side close with error) and reconnect is disabled or fails, leaving queued sends undelivered.","commonSituations":"Unstable networks, proxies/load balancers with short idle timeouts, sending after the server already closed the connection, or background tasks enqueueing sends while the main task is closing the stream.","solutions":["Catch WebSocketConnectionClosedError and inspect .unsent_messages to know what failed to deliver; decide whether to resend on a new connection","Check connectivity/proxy configuration if closures are frequent","Avoid sending while the connection is closing; drain/await sends before exiting the context manager"],"exampleFix":"// before\nasync for event in conn:\n    ...\n// after\nfrom openai._websocket import WebSocketConnectionClosedError\ntry:\n    async for event in conn:\n        ...\nexcept WebSocketConnectionClosedError as exc:\n    for msg in exc.unsent_messages:\n        await new_conn.send(msg)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from openai._websocket import WebSocketConnectionClosedError\n\ntry:\n    async for event in conn:\n        handle(event)\nexcept WebSocketConnectionClosedError as exc:\n    retry_with(exc.unsent_messages)","preventionTips":["Complete pending sends before exiting the connection context","Monitor connection health and stop producers when the socket is down","Wrap the iteration loop in reconnect logic for long-lived realtime sessions"],"tags":["python","websocket","responses-api","network","async"],"backgroundTag":"websocket-connection-closed","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}