openai/openai-python · error · WebSocketConnectionClosedError

WebSocket connection closed with unsent messages

Error message

WebSocket connection closed with unsent messages

What it means

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.

Source

Thrown at src/openai/resources/realtime/realtime.py:320

        self.output_audio_buffer = AsyncRealtimeOutputAudioBufferResource(self)

    async def __aiter__(self) -> AsyncIterator[RealtimeServerEvent]:
        """
        An infinite-iterator that will continue to yield events until
        the connection is closed.
        """
        from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError

        while True:
            try:
                yield await self.recv()
            except ConnectionClosedOK:
                return
            except ConnectionClosedError as exc:
                if not await self._reconnect(exc):
                    unsent = self._send_queue.drain()
                    if unsent:
                        raise WebSocketConnectionClosedError(
                            "WebSocket connection closed with unsent messages",
                            unsent_messages=unsent,
                        ) from exc
                    raise

    async def recv(self) -> RealtimeServerEvent:
        """
        Receive the next message from the connection and parses it into a `RealtimeServerEvent` object.

        Canceling this method is safe. There's no risk of losing data.
        """
        return self.parse_event(await self.recv_bytes())

    async def recv_bytes(self) -> bytes:
        """Receive the next message from the connection as raw bytes.

        Canceling this method is safe. There's no risk of losing data.

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Catch WebSocketConnectionClosedError and inspect `.unsent_messages` to decide what to resend after reconnecting
  2. Open a fresh connection (new context manager) and re-send the unsent messages idempotently
  3. Add retry/backoff around session creation for transient network drops
  4. Avoid queueing large bursts while the connection is unhealthy; check conn state before send

Example fix

# before
async for event in conn:
    handle(event)
# after
from openai import WebSocketConnectionClosedError
try:
    async for event in conn:
        handle(event)
except WebSocketConnectionClosedError as exc:
    for msg in exc.unsent_messages:
        logger.warning("unsent: %r", msg)
    # reconnect and re-send unsent_messages
Defensive patterns

Strategy: retry

Validate before calling

# Check connection health before sending
if conn.session is None:
    logger.warning("connection not ready; queueing paused")

Try / catch

from openai import WebSocketConnectionClosedError
try:
    async for event in conn:
        handle(event)
except WebSocketConnectionClosedError as exc:
    unsent = exc.unsent_messages
    # reconnect and re-send unsent

Prevention

When it happens

Trigger: 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.

Common situations: Long-lived realtime sessions behind flaky networks, sending bursts of events during a disconnect window, auth token expiry preventing reconnection.

Understand the failure class

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/9c1c1420463cd643. Report an issue: GitHub.