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

  1. Ensure the orchestration feeds the transform with ChatMessageContent or list[ChatMessageContent] (i.e. the orchestration's internal output stays as chat content).
  2. Move the structured-output transform to a position where it receives raw chat content, before any other transform converts it.
  3. If you already have a structured object, call target_structure.model_validate_json on it directly instead of using this transform.
  4. 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

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


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