microsoft/semantic-kernel · error · ValueError
Output must be {DefaultTypeAlias}.
Error message
Output must be {DefaultTypeAlias}. What it means
Raised inside the structured-output transform when the value handed to it is neither a ChatMessageContent nor a list of ChatMessageContent. The transform needs to append the assistant output to a ChatHistory before re-calling the service with response_format set, so any non-chat shape is unusable.
Source
Thrown at python/semantic_kernel/agents/orchestration/tools.py:60
raise ValueError("The service must support structured output.")
settings.response_format = target_structure
chat_history = ChatHistory(
system_message=(
"Try your best to summarize the conversation into structured format:\n"
f"{target_structure.model_json_schema()}."
),
)
async def output_transform(output: DefaultTypeAlias) -> BaseModel:
"""Transform the output of the chat completion service into the target structure."""
if isinstance(output, ChatMessageContent):
chat_history.add_message(output)
elif isinstance(output, list) and all(isinstance(item, ChatMessageContent) for item in output):
for item in output:
chat_history.add_message(item)
else:
raise ValueError(f"Output must be {DefaultTypeAlias}.")
response = await service.get_chat_message_content(chat_history, settings)
assert response is not None # nosec B101
return target_structure.model_validate_json(response.content)
return output_transform
View on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure the orchestration feeds the transform with ChatMessageContent or list[ChatMessageContent] (i.e. the orchestration's internal output stays as chat content).
- Move the structured-output transform to a position where it receives raw chat content, before any other transform converts it.
- If you already have a structured object, call target_structure.model_validate_json on it directly instead of using this transform.
- Inspect type(output) at the call site and fix the upstream producer to emit ChatMessageContent.
Example fix
// before
orch = MyOrchestration(output_transform=get_response_from_structured_output_tool(service, MyModel))
# upstream returns a dict -> triggers [944]
// after
async def to_chat_then_structured(out):
if not isinstance(out, ChatMessageContent):
out = ChatMessageContent(role=AuthorRole.ASSISTANT, content=json.dumps(out))
return await get_response_from_structured_output_tool(service, MyModel)(out)
orch = MyOrchestration(output_transform=to_chat_then_structured) Defensive patterns
Strategy: type-guard
Validate before calling
from semantic_kernel.contents import ChatMessageContent
def is_structured_tool_input(output) -> bool:
if isinstance(output, ChatMessageContent):
return True
return isinstance(output, list) and all(isinstance(i, ChatMessageContent) for i in output) Type guard
from typing import Any
from semantic_kernel.contents import ChatMessageContent
def is_chat_or_chat_list(value: Any) -> bool:
if isinstance(value, ChatMessageContent):
return True
return isinstance(value, list) and bool(value) and all(isinstance(i, ChatMessageContent) for i in value) Try / catch
try:
result = await transform(output)
except ValueError as e:
if "Output must be" in str(e):
if not isinstance(output, ChatMessageContent):
output = ChatMessageContent(role=AuthorRole.ASSISTANT, content=str(output))
result = await transform(output)
else:
raise Prevention
- Feed the structured-output transform only with ChatMessageContent or list of it.
- Place the transform before any conversion to structured objects.
- If you already have a structured object, validate it directly instead of using this transform.
- Log type(output) at transform boundaries during development.
When it happens
Trigger: A transform produced by get_response_from_structured_output_tool is wired into an orchestration whose output_message is something other than ChatMessageContent or list[ChatMessageContent] (e.g. a pydantic model already deserialized, a dict, or None).
Common situations: Combining the structured-output tool as an output_transform on an orchestration whose upstream agent returns a structured object rather than chat content; reusing the transform on a sequential chain whose previous step returns a non-chat type; a None returned by an empty/failed agent.
Related errors
- Invalid input message type: {type(input_message)}. Expected
- Invalid output message type: {type(output_message)}. Expecte
- Unable to transform output message of type {type(output_mess
- The service must support structured output.
- Unable to transform result into {typeof(TOutput).Name}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/83e057455488f1e7.
Report an issue: GitHub.