openai/openai-python · error · MissingStreamClassError

MissingStreamClassError

Error message

MissingStreamClassError

What it means

Parsing an SSE streaming response requires a stream class to wrap the response iterator, and the client's _default_stream_cls is None. This happens when the response object isn't bound to a client that provides a default stream class (e.g. manually constructed responses or a misconfigured custom client), so MissingStreamClassError is raised.

Source

Thrown at src/openai/_response.py:173

                        client=cast(Any, self._client),
                        options=self._options,
                    ),
                )

            if self._stream_cls:
                return cast(
                    R,
                    self._stream_cls(
                        cast_to=extract_stream_chunk_type(self._stream_cls),
                        response=self.http_response,
                        client=cast(Any, self._client),
                        options=self._options,
                    ),
                )

            stream_cls = cast("type[Stream[Any]] | type[AsyncStream[Any]] | None", self._client._default_stream_cls)
            if stream_cls is None:
                raise MissingStreamClassError()

            return cast(
                R,
                stream_cls(
                    cast_to=cast_to,
                    response=self.http_response,
                    client=cast(Any, self._client),
                    options=self._options,
                ),
            )

        if cast_to is NoneType:
            return cast(R, None)

        response = self.http_response
        if cast_to == str:
            return cast(R, response.text)

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Use the real client returned by OpenAI()/AsyncOpenAI() rather than constructing response objects manually
  2. In tests, mock at the HTTP transport layer instead of building bare response objects
  3. If subclassing the client, don't set _default_stream_cls to None; leave the inherited Stream/AsyncStream default

Example fix

// before
resp = construct_type(value=data, type_=APIResponse)
resp.parse()  # client missing -> MissingStreamClassError
// after
resp = await client.chat.completions.with_raw_response.create(..., stream=True)
resp.parse()  # client supplies default stream class
Defensive patterns

Strategy: try-catch

Validate before calling

from openai._response import MissingStreamClassError
if getattr(client, '_default_stream_cls', None) is None:
    raise RuntimeError('client missing default stream class; use OpenAI()/AsyncOpenAI()')

Type guard

def client_has_stream_class(client) -> bool:
    return getattr(client, '_default_stream_cls', None) is not None

Try / catch

from openai._response import MissingStreamClassError

try:
    stream = response.parse()
except MissingStreamClassError:
    logger.error('response not bound to a real client')
    raise

Prevention

When it happens

Trigger: Calling response.parse() on an SSE response whose client lacks a default stream class — detached/manually built response objects, or a custom client subclass that overrode _default_stream_cls with None.

Common situations: Mocking or faking the client/response in tests without setting the stream class; custom client wrappers that reset internal defaults; upgrading across major versions where client internals changed.

Related errors


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