microsoft/semantic-kernel · error · TypeError

Invalid input message type: {type(input_message)}. Expected

Error message

Invalid input message type: {type(input_message)}. Expected {self.t_in}.

What it means

Raised by the orchestration base's default input transform when the value passed into the orchestration is not ChatMessageContent, a list of ChatMessageContent, or an instance of the orchestration's configured input type (self.t_in). The default transform only knows how to convert these three shapes into chat content, so anything else is rejected. This fires when you invoke the orchestration with a message whose type does not match the generic TIn you declared.

Source

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

        Args:
            input_message (TIn): The input message to be transformed.

        Returns:
            DefaultTypeAlias: The transformed input message.
        """
        if isinstance(input_message, ChatMessageContent):
            return input_message

        if isinstance(input_message, list) and all(isinstance(item, ChatMessageContent) for item in input_message):
            return input_message

        if isinstance(input_message, self.t_in):  # type: ignore[arg-type]
            return ChatMessageContent(
                role=AuthorRole.USER,
                content=json.dumps(input_message.__dict__),
            )

        raise TypeError(f"Invalid input message type: {type(input_message)}. Expected {self.t_in}.")

    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)
            ):

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Pass a value whose type matches the orchestration's declared TIn (self.t_in), or pass a ChatMessageContent / list[ChatMessageContent] directly.
  2. If you need a custom external input type, register an input_transform callable so the default transform is bypassed: orchestration = MyOrchestration(input_transform=my_transform).
  3. Verify the generic parameter at construction, e.g. GroupChat[input_type, output_type](...), and ensure the value you pass is an instance of input_type.
  4. If you intended to send plain text, wrap it first: ChatMessageContent(role=AuthorRole.USER, content=text).

Example fix

// before
await my_orchestration.invoke("hello world", threads=...)
// after
from semantic_kernel.contents import ChatMessageContent, AuthorRole
await my_orchestration.invoke(
    ChatMessageContent(role=AuthorRole.USER, content="hello world"),
    threads=...,
)
Defensive patterns

Strategy: type-guard

Validate before calling

from semantic_kernel.contents import ChatMessageContent

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

Type guard

from typing import Any
from semantic_kernel.contents import ChatMessageContent

def is_orchestration_input(value: Any) -> bool:
    if isinstance(value, ChatMessageContent):
        return True
    return isinstance(value, list) and all(isinstance(i, ChatMessageContent) for i in value)

Try / catch

try:
    result = await orchestration.invoke(message, threads=threads)
except TypeError as e:
    if "Invalid input message type" in str(e):
        message = ChatMessageContent(role=AuthorRole.USER, content=str(message))
        result = await orchestration.invoke(message, threads=threads)
    else:
        raise

Prevention

When it happens

Trigger: Calling an orchestration's invoke/invoke_stream with a payload (e.g. a raw str, dict, int, or a custom dataclass) that is not an instance of the orchestration's t_in generic parameter, and not already ChatMessageContent or a list of them. Occurs when t_in is left as a non-matching default or when the caller forgets to set an input_transform.

Common situations: Misconfiguring an orchestration's generic types (e.g. GroupChat[TIn=str] but passing an int), upgrading to a version where TIn defaults changed, passing a pydantic model instance whose class is not the declared t_in, or reusing an orchestration across pipelines that emit different message types.

Related errors


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