openai/openai-python · error · TypeError

You tried to pass a `BaseModel` class to `chat.completions.c

Error message

You tried to pass a `BaseModel` class to `chat.completions.create()`; You must use `chat.completions.parse()` instead

What it means

validate_response_format rejects passing a pydantic BaseModel subclass as response_format to chat.completions.create(). Structured outputs via a BaseModel class require the dedicated client.beta.chat.completions.parse() method, which handles schema generation and parsing; create() only accepts a dict-based response_format (e.g. json_schema specs). This is a TypeError raised synchronously before any request.

Source

Thrown at src/openai/resources/chat/completions/completions.py:3409

        )
        self.list = async_to_streamed_response_wrapper(
            completions.list,
        )
        self.delete = async_to_streamed_response_wrapper(
            completions.delete,
        )

    @cached_property
    def messages(self) -> AsyncMessagesWithStreamingResponse:
        """
        Given a list of messages comprising a conversation, the model will return a response.
        """
        return AsyncMessagesWithStreamingResponse(self._completions.messages)


def validate_response_format(response_format: object) -> None:
    if inspect.isclass(response_format) and issubclass(response_format, pydantic.BaseModel):
        raise TypeError(
            "You tried to pass a `BaseModel` class to `chat.completions.create()`; You must use `chat.completions.parse()` instead"
        )

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Use `client.beta.chat.completions.parse(..., response_format=MyModel)` for typed structured outputs.
  2. If you must use create(), pass a dict spec such as `{"type": "json_schema", "json_schema": {"name": "my_schema", "schema": MyModel.model_json_schema()}}` (per the chat.completions.create docs).
  3. Do not pass the class anywhere else (e.g. inside message content).

Example fix

# before
completion = client.chat.completions.create(
    model="gpt-4o", messages=[...], response_format=MyModel
)
# after
completion = client.beta.chat.completions.parse(
    model="gpt-4o", messages=[...], response_format=MyModel
)
# or with create():
completion = client.chat.completions.create(
    model="gpt-4o", messages=[...],
    response_format={"type": "json_schema", "json_schema": {"name": "out", "schema": MyModel.model_json_schema(), "strict": True}},
)
Defensive patterns

Strategy: type-guard

Validate before calling

import pydantic

def check_response_format(rf: object) -> None:
    if inspect.isclass(rf) and issubclass(rf, pydantic.BaseModel):
        raise TypeError("use client.beta.chat.completions.parse() for BaseModel response_format")

Type guard

def uses_base_model(rf: object) -> bool:
    import inspect, pydantic
    return inspect.isclass(rf) and issubclass(rf, pydantic.BaseModel)

# route: parse() if uses_base_model(fmt) else create()

Try / catch

try:
    completion = client.chat.completions.create(..., response_format=fmt)
except TypeError as e:
    if "parse()" in str(e):
        completion = client.beta.chat.completions.parse(..., response_format=fmt)
    else:
        raise

Prevention

When it happens

Trigger: `client.chat.completions.create(model="gpt-4o", messages=[...], response_format=MyPydanticModel)` where MyPydanticModel subclasses pydantic.BaseModel.

Common situations: Migrating code from the parse() structured-output API back to create(), or following tutorials that show structured outputs and wiring the model class into the wrong method; also passing a BaseModel where a `{"type": "json_schema", ...}` dict is expected.

Related errors


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