microsoft/semantic-kernel · error · TypeError

Invalid output message type: {type(output_message)}. Expecte

Error message

Invalid output message type: {type(output_message)}. Expected {self.t_out}.

What it means

Raised inside _default_output_transform when the orchestration's output type is the default alias (ChatMessageContent | list[ChatMessageContent]) but the actual internal output message is neither a single ChatMessageContent nor a homogeneous list of them. The default-output branch trusts that downstream actors produce chat content; any other shape is a programming error in the orchestration pipeline or a custom transform that returned the wrong type.

Source

Thrown at python/semantic_kernel/agents/orchestration/orchestration_base.py:339

    def _default_output_transform(self, output_message: DefaultTypeAlias) -> TOut:
        """Default output transform function.

        This function transforms the internal output message to the external output message.
        If the output message is already in the correct format, it is returned as is.

        Args:
            output_message (DefaultTypeAlias): The output message to be transformed.

        Returns:
            TOut: The transformed output message.
        """
        if self.t_out == DefaultTypeAlias or self.t_out in get_args(DefaultTypeAlias):
            if isinstance(output_message, ChatMessageContent) or (
                isinstance(output_message, list)
                and all(isinstance(item, ChatMessageContent) for item in output_message)
            ):
                return output_message  # type: ignore[return-value]
            raise TypeError(f"Invalid output message type: {type(output_message)}. Expected {self.t_out}.")

        if isinstance(output_message, ChatMessageContent):
            return self.t_out(**json.loads(output_message.content))  # type: ignore[misc]

        raise TypeError(f"Unable to transform output message of type {type(output_message)} to {self.t_out}.")

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure every component feeding the orchestration output returns ChatMessageContent or list[ChatMessageContent] when t_out is the default alias.
  2. If you need a structured output type, set the orchestration generic/output type so it takes the typed branch instead (e.g. MyOrchestration[..., MyModel]) and supply an output_transform.
  3. Inspect the value reported by type(output_message) in the error and fix the producing transform to return the correct shape.
  4. Wrap non-chat returns: return ChatMessageContent(role=AuthorRole.ASSISTANT, content=json.dumps(obj)).

Example fix

// before
async def my_output_transform(output):
    return {"text": output.content}   # dict -> triggers [941]
// after
from semantic_kernel.contents import ChatMessageContent, AuthorRole
async def my_output_transform(output):
    return ChatMessageContent(role=AuthorRole.ASSISTANT, content=output.content)
Defensive patterns

Strategy: type-guard

Validate before calling

from semantic_kernel.contents import ChatMessageContent

def is_default_output(msg) -> bool:
    if isinstance(msg, ChatMessageContent):
        return True
    return isinstance(msg, list) and all(isinstance(i, ChatMessageContent) for i in msg)

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:
    out = await orchestration.invoke(...)
except TypeError as e:
    if "Invalid output message type" in str(e):
        # fix upstream producer or supply an output_transform
        raise
    raise

Prevention

When it happens

Trigger: The orchestration's t_out equals DefaultTypeAlias (or one of its args) and an internal actor, agent, or a user-supplied intermediate transform returned something that is not ChatMessageContent and not a list of ChatMessageContent. Also triggered by returning None, a tuple, a dict, or a pydantic model from a transform wired into the default-output path.

Common situations: Plugging a custom agent whose invoke returns StreamingChatMessageContent or a raw string into a default-output orchestration; a transform that accidentally returns a tuple instead of a list; mixing concurrent and sequential orchestration whose message shapes disagree.

Related errors


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