microsoft/semantic-kernel · error · ServiceInvalidExecutionSettingsError
If response_format has type 'json_schema', 'json_schema' mus
Error message
If response_format has type 'json_schema', 'json_schema' must be a valid dictionary.
What it means
When the response_format dict has type 'json_schema', the OpenAI structured outputs API requires a 'json_schema' key containing a valid dictionary (the actual JSON Schema definition). The model_validator detects that response_format['type'] == 'json_schema' but response_format['json_schema'] is either missing or not a dict, and raises ServiceInvalidExecutionSettingsError.
Source
Thrown at python/semantic_kernel/connectors/ai/open_ai/prompt_execution_settings/open_ai_prompt_execution_settings.py:134
@model_validator(mode="before")
def validate_response_format_and_set_flag(cls, values: Any) -> Any:
"""Validate the response_format and set structured_json_response accordingly."""
if not isinstance(values, dict):
return values
response_format = values.get("response_format", None)
if response_format is None:
return values
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."""
View on GitHub (pinned to c028a0c7dc)
Solutions
- Structure the dict correctly: response_format={'type': 'json_schema', 'json_schema': {'name': 'my_schema', 'schema': {...actual_schema...}}}.
- Pass a pydantic BaseModel subclass directly as response_format — the validator handles the conversion.
- Validate the dict shape before assignment with a helper that checks json_schema key presence and type.
Example fix
// before
settings.response_format = {'type': 'json_schema', 'json_schema': MyClass.model_json_schema()}
// after
settings.response_format = {'type': 'json_schema', 'json_schema': {'name': 'my_class', 'schema': MyClass.model_json_schema()}}
// or simply:
settings.response_format = MyClass # pass the BaseModel subclass directly Defensive patterns
Strategy: validation
Validate before calling
def validate_json_schema_response_format(response_format: dict) -> None:
if response_format.get('type') == 'json_schema':
js = response_format.get('json_schema')
if not isinstance(js, dict):
raise ValueError(
"response_format with type 'json_schema' requires 'json_schema' to be a dict, "
f'got {type(js).__name__}'
)
if 'name' not in js:
raise ValueError("json_schema must contain a 'name' key") Type guard
def is_valid_json_schema_response_format(response_format: dict) -> bool:
if response_format.get('type') != 'json_schema':
return True
js = response_format.get('json_schema')
return isinstance(js, dict) and 'name' in js Try / catch
from semantic_kernel.exceptions import ServiceInvalidExecutionSettingsError
try:
settings = OpenAIChatPromptExecutionSettings(response_format=rf)
except ServiceInvalidExecutionSettingsError as e:
if 'json_schema' in str(e):
rf['json_schema'] = {'name': 'output', 'schema': rf.pop('json_schema')}
settings = OpenAIChatPromptExecutionSettings(response_format=rf) Prevention
- Pass a pydantic BaseModel subclass directly as response_format to let the SDK handle structuring.
- If building the dict manually, always include 'name' and 'schema' keys under 'json_schema'.
- Write a factory function that constructs valid response_format dicts to avoid ad-hoc bugs.
When it happens
Trigger: Passing response_format={'type': 'json_schema', 'json_schema': 'my_schema_string'} or response_format={'type': 'json_schema'} (missing key) to OpenAIChatPromptExecutionSettings. Common when building the dict dynamically or from a malformed config.
Common situations: Serializing a pydantic model to a response_format dict incorrectly (e.g. using model_json_schema() as the top-level value instead of nesting under 'json_schema'); passing the schema name string instead of the schema dict; malformed config files from manual editing.
Related errors
- When used with number_of_responses, best_of controls the num
- response_format must be a dictionary, a subclass of BaseMode
- Invalid image size: {size.width}x{size.height}.
- OPENAI_API_KEY is not set.
- OPENAI_API_KEY is not set.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/a1110377a7c1aa1d.
Report an issue: GitHub.