{"record":{"id":"83e057455488f1e7","repo":"microsoft/semantic-kernel","slug":"output-must-be-defaulttypealias","errorCode":null,"errorMessage":"Output must be {DefaultTypeAlias}.","messagePattern":"Output must be (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/orchestration/tools.py","lineNumber":60,"sourceCode":"        raise ValueError(\"The service must support structured output.\")\n    settings.response_format = target_structure\n\n    chat_history = ChatHistory(\n        system_message=(\n            \"Try your best to summarize the conversation into structured format:\\n\"\n            f\"{target_structure.model_json_schema()}.\"\n        ),\n    )\n\n    async def output_transform(output: DefaultTypeAlias) -> BaseModel:\n        \"\"\"Transform the output of the chat completion service into the target structure.\"\"\"\n        if isinstance(output, ChatMessageContent):\n            chat_history.add_message(output)\n        elif isinstance(output, list) and all(isinstance(item, ChatMessageContent) for item in output):\n            for item in output:\n                chat_history.add_message(item)\n        else:\n            raise ValueError(f\"Output must be {DefaultTypeAlias}.\")\n\n        response = await service.get_chat_message_content(chat_history, settings)\n        assert response is not None  # nosec B101\n\n        return target_structure.model_validate_json(response.content)\n\n    return output_transform\n","sourceCodeStart":42,"sourceCodeEnd":68,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/orchestration/tools.py#L42-L68","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\norch = MyOrchestration(output_transform=get_response_from_structured_output_tool(service, MyModel))\n# upstream returns a dict -> triggers [944]\n// after\nasync def to_chat_then_structured(out):\n    if not isinstance(out, ChatMessageContent):\n        out = ChatMessageContent(role=AuthorRole.ASSISTANT, content=json.dumps(out))\n    return await get_response_from_structured_output_tool(service, MyModel)(out)\norch = MyOrchestration(output_transform=to_chat_then_structured)","handlingStrategy":"type-guard","validationCode":"from semantic_kernel.contents import ChatMessageContent\n\ndef is_structured_tool_input(output) -> bool:\n    if isinstance(output, ChatMessageContent):\n        return True\n    return isinstance(output, list) and all(isinstance(i, ChatMessageContent) for i in output)","typeGuard":"from typing import Any\nfrom semantic_kernel.contents import ChatMessageContent\n\ndef is_chat_or_chat_list(value: Any) -> bool:\n    if isinstance(value, ChatMessageContent):\n        return True\n    return isinstance(value, list) and bool(value) and all(isinstance(i, ChatMessageContent) for i in value)","tryCatchPattern":"try:\n    result = await transform(output)\nexcept ValueError as e:\n    if \"Output must be\" in str(e):\n        if not isinstance(output, ChatMessageContent):\n            output = ChatMessageContent(role=AuthorRole.ASSISTANT, content=str(output))\n        result = await transform(output)\n    else:\n        raise","preventionTips":["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."],"tags":["orchestration","structured-output","type-mismatch","semantic-kernel"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}