microsoft/semantic-kernel · error · ServiceInvalidExecutionSettingsError

response_format must be a dictionary, a subclass of BaseMode

Error message

response_format must be a dictionary, a subclass of BaseModel, a Python class/type, or None

What it means

The response_format field on OpenAIChatPromptExecutionSettings only accepts one of: a dict, a pydantic BaseModel subclass, a plain Python class/type, or None. If none of these isinstance/issubclass checks match (e.g. passing an instance object, a list, a string, or an integer), the validator falls through to the else branch and raises ServiceInvalidExecutionSettingsError.

Source

Thrown at python/semantic_kernel/connectors/ai/open_ai/prompt_execution_settings/open_ai_prompt_execution_settings.py:143

        if isinstance(response_format, dict):
            if response_format.get("type") == "json_object":
                return values
            if response_format.get("type") == "json_schema":
                json_schema = response_format.get("json_schema")
                if isinstance(json_schema, dict):
                    values["structured_json_response"] = True
                    return values
                raise ServiceInvalidExecutionSettingsError(
                    "If response_format has type 'json_schema', 'json_schema' must be a valid dictionary."
                )
        if isinstance(response_format, type):
            if issubclass(response_format, BaseModel):
                values["structured_json_response"] = True
            else:
                values["structured_json_response"] = True
        else:
            raise ServiceInvalidExecutionSettingsError(
                "response_format must be a dictionary, a subclass of BaseModel, a Python class/type, or None"
            )

        return values


class OpenAIEmbeddingPromptExecutionSettings(PromptExecutionSettings):
    """Specific settings for the text embedding endpoint."""

    input: str | list[str] | list[int] | list[list[int]] | None = None
    ai_model_id: Annotated[str | None, Field(serialization_alias="model")] = None
    encoding_format: Literal["float", "base64"] | None = None
    user: str | None = None
    extra_headers: dict | None = None
    extra_query: dict | None = None
    extra_body: dict | None = None
    timeout: float | None = None
    dimensions: Annotated[int | None, Field(gt=0, le=3072)] = None

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Pass the BaseModel subclass (the type), not an instance: response_format=MyModel, not MyModel().
  2. If passing a string, parse it first: response_format=json.loads(my_string) so it becomes a dict.
  3. Set response_format to None to disable structured output entirely.

Example fix

// before
settings.response_format = MyModel()  # instance — fails
// after
settings.response_format = MyModel  # class/type — works
Defensive patterns

Strategy: type-guard

Validate before calling

from pydantic import BaseModel

def validate_response_format(response_format) -> None:
    if response_format is None:
        return
    if isinstance(response_format, dict):
        return
    if isinstance(response_format, type) and issubclass(response_format, BaseModel):
        return
    if isinstance(response_format, type):
        return
    raise TypeError(
        'response_format must be a dict, a BaseModel subclass, a Python type, or None; '
        f'got {type(response_format).__name__}'
    )

Type guard

from pydantic import BaseModel

def is_valid_response_format(rf) -> bool:
    if rf is None:
        return True
    if isinstance(rf, dict):
        return True
    if isinstance(rf, type) and (issubclass(rf, BaseModel) or True):
        return True
    return False

Try / catch

from semantic_kernel.exceptions import ServiceInvalidExecutionSettingsError

try:
    settings = OpenAIChatPromptExecutionSettings(response_format=rf)
except ServiceInvalidExecutionSettingsError as e:
    if 'must be a dictionary' in str(e):
        rf = type(rf) if isinstance(rf, BaseModel) else rf  # pass class not instance
        settings = OpenAIChatPromptExecutionSettings(response_format=rf)

Prevention

When it happens

Trigger: Passing an already-instantiated BaseModel object (not the class) as response_format; passing a list, tuple, string, or number; passing a JSON string instead of a parsed dict.

Common situations: Confusing the class and instance: response_format=MyModel() instead of response_format=MyModel; passing a JSON-encoded string from an API payload without json.loads(); passing a frozenset or other non-type non-dict object.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/958510311f1261ac. Report an issue: GitHub.