{"record":{"id":"9c1c1420463cd643","repo":"openai/openai-python","slug":"websocket-connection-closed-with-unsent-messages-9c1c14","errorCode":null,"errorMessage":"WebSocket connection closed with unsent messages","messagePattern":"WebSocket connection closed with unsent messages","errorType":"exception","errorClass":"WebSocketConnectionClosedError","httpStatus":null,"severity":"error","filePath":"src/openai/resources/realtime/realtime.py","lineNumber":320,"sourceCode":"        self.output_audio_buffer = AsyncRealtimeOutputAudioBufferResource(self)\n\n    async def __aiter__(self) -> AsyncIterator[RealtimeServerEvent]:\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) -> RealtimeServerEvent:\n        \"\"\"\n        Receive the next message from the connection and parses it into a `RealtimeServerEvent` 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":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/resources/realtime/realtime.py#L302-L338","documentation":"Raised while iterating an async Realtime websocket connection: the connection closed with an error, reconnection attempts were exhausted or impossible, and the outgoing send queue still contained undelivered messages. The SDK surfaces WebSocketConnectionClosedError carrying the unsent messages so callers know which client events never reached the server.","triggerScenarios":"Async iteration (`async for event in conn`) while concurrently send()ing events; the socket dies (network drop, server close) and reconnect fails with queued events still pending.","commonSituations":"Long-lived realtime sessions behind flaky networks, sending bursts of events during a disconnect window, auth token expiry preventing reconnection.","solutions":["Catch WebSocketConnectionClosedError and inspect `.unsent_messages` to decide what to resend after reconnecting","Open a fresh connection (new context manager) and re-send the unsent messages idempotently","Add retry/backoff around session creation for transient network drops","Avoid queueing large bursts while the connection is unhealthy; check conn state before send"],"exampleFix":"# before\nasync for event in conn:\n    handle(event)\n# after\nfrom openai import WebSocketConnectionClosedError\ntry:\n    async for event in conn:\n        handle(event)\nexcept WebSocketConnectionClosedError as exc:\n    for msg in exc.unsent_messages:\n        logger.warning(\"unsent: %r\", msg)\n    # reconnect and re-send unsent_messages","handlingStrategy":"retry","validationCode":"# Check connection health before sending\nif conn.session is None:\n    logger.warning(\"connection not ready; queueing paused\")","typeGuard":null,"tryCatchPattern":"from openai import WebSocketConnectionClosedError\ntry:\n    async for event in conn:\n        handle(event)\nexcept WebSocketConnectionClosedError as exc:\n    unsent = exc.unsent_messages\n    # reconnect and re-send unsent","preventionTips":["Always register an error handler and drain unsent messages on close","Wrap realtime sessions in reconnect-with-backoff loops","Avoid large send bursts during degraded networks","Make sent events idempotent so re-sends are safe"],"tags":["realtime","websocket","async","reconnect","network"],"backgroundTag":"websocket-connection-closed","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}