openai/openai-python · error · WebSocketConnectionClosedError

WebSocket connection closed with unsent messages

Error message

WebSocket connection closed with unsent messages

What it means

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.

Source

Thrown at src/openai/resources/beta/responses/responses.py:4155

        self.response = AsyncResponsesResponseResource(self)

    async def __aiter__(self) -> AsyncIterator[BetaResponsesServerEvent]:
        """
        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) -> BetaResponsesServerEvent:
        """
        Receive the next message from the connection and parses it into a `BetaResponsesServerEvent` 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 know what failed to deliver; decide whether to resend on a new connection
  2. Check connectivity/proxy configuration if closures are frequent
  3. Avoid sending while the connection is closing; drain/await sends before exiting the context manager

Example fix

// before
async for event in conn:
    ...
// after
from openai._websocket import WebSocketConnectionClosedError
try:
    async for event in conn:
        ...
except WebSocketConnectionClosedError as exc:
    for msg in exc.unsent_messages:
        await new_conn.send(msg)
Defensive patterns

Strategy: try-catch

Try / catch

from openai._websocket import WebSocketConnectionClosedError

try:
    async for event in conn:
        handle(event)
except WebSocketConnectionClosedError as exc:
    retry_with(exc.unsent_messages)

Prevention

When it happens

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

Common situations: 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.

Understand the failure class

Related errors


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