openai/openai-python · error · RuntimeError

Unsupported type, expected {cast_to} to be a subclass of {Ba

Error message

Unsupported type, expected {cast_to} to be a subclass of {BaseModel}, {dict}, {list}, {Union}, {NoneType}, {str} or {httpx2.Response}.

What it means

The runtime cast_to validation allows only: the SDK BaseModel, dict, list, Union, None, str, or httpx.Response (and object). Any other class — or a non-class value such as a string or instance — reaches this branch and raises a RuntimeError listing the supported types.

Source

Thrown at src/openai/_legacy_response.py:305

            return cast(R, response)

        if (
            inspect.isclass(
                origin  # pyright: ignore[reportUnknownArgumentType]
            )
            and not issubclass(origin, BaseModel)
            and issubclass(origin, pydantic.BaseModel)
        ):
            raise TypeError("Pydantic models must subclass our base model type, e.g. `from openai import BaseModel`")

        if (
            cast_to is not object
            and not origin is list
            and not origin is dict
            and not origin is Union
            and not issubclass(origin, BaseModel)
        ):
            raise RuntimeError(
                f"Unsupported type, expected {cast_to} to be a subclass of {BaseModel}, {dict}, {list}, {Union}, {NoneType}, {str} or {httpx2.Response}."
            )

        # split is required to handle cases where additional information is included
        # in the response, e.g. application/json; charset=utf-8
        content_type, *_ = response.headers.get("content-type", "*").split(";")
        if not content_type.endswith("json"):
            if is_basemodel(cast_to):
                try:
                    data = response.json()
                except Exception as exc:
                    log.debug("Could not read JSON from response data due to %s", type(exc).__name__)
                else:
                    return self._client._process_response_data(
                        data=data,
                        cast_to=cast_to,  # type: ignore
                        response=response,
                    )

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Ensure cast_to is an actual class deriving from openai.BaseModel (or dict/list/Union/None/str/httpx.Response)
  2. If cast_to comes from a string, resolve it via a registry: {'my_model': MyModel}.get(name)
  3. Add a unit test asserting the configured cast_to value passes issubclass(x, BaseModel) or is in the allowed set

Example fix

# before
resp = client.get('/models', cast_to='Model', ...)
# after
resp = client.get('/models', cast_to=Model, ...)
Defensive patterns

Strategy: type-guard

Validate before calling

from openai import BaseModel
import httpx, typing
ALLOWED_EXACT = {dict, list, str, httpx.Response, object, None}
def check_cast(t):
    ok = t in ALLOWED_EXACT or (isinstance(t, type) and issubclass(t, BaseModel)) or typing.get_origin(t) is typing.Union
    assert ok, f'unsupported cast_to: {t!r}'
check_cast(cast_to)

Type guard

def is_supported_cast_to(t: object) -> bool:
    import typing, httpx
    from openai import BaseModel
    return t in {dict, list, str, httpx.Response, object} or (isinstance(t, type) and issubclass(t, BaseModel)) or typing.get_origin(t) is typing.Union

Try / catch

try:
    parsed = response.parse()
except RuntimeError as e:
    if 'Unsupported type' in str(e):
        parsed = response.parse() if False else response.text

Prevention

When it happens

Trigger: Passing cast_to=str-typo values like cast_to='MyModel' (a string instead of a class), cast_to=int/float/tuple/typing.Any-like objects, or a class not deriving from the allowed roots; also passing a generic alias the parser does not recognize.

Common situations: Dynamically computing cast_to from a mapping or config string and forgetting to resolve it to the actual class; passing typing constructs unsupported by this parser; refactors that change a model's base class.

Related errors


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