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
- Pass a value whose type matches the orchestration's declared TIn (self.t_in), or pass a ChatMessageContent / list[ChatMessageContent] directly.
- 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).
- 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.
- 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
- Always declare explicit TIn/TOut generics on orchestration construction.
- Pass ChatMessageContent or list[ChatMessageContent] when unsure of the configured t_in.
- Provide a custom input_transform for non-chat external types instead of relying on the default.
- Unit-test the input boundary with each message shape your pipeline emits.
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
- Invalid output message type: {type(output_message)}. Expecte
- Unable to transform output message of type {type(output_mess
- Output must be {DefaultTypeAlias}.
- A complete listen_for condition is required for orchestratio
- At least one then action is required for orchestration steps
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/0c1bd57217e1eaa2.
Report an issue: GitHub.