microsoft/semantic-kernel · error · ValueError

Invalid message body type: {type(message.body)}. Expected {D

Error message

Invalid message body type: {type(message.body)}. Expected {DefaultTypeAlias}.

What it means

Raised as a ValueError in HandoffActor._handle_start_message when the incoming HandoffStartMessage.body is neither a ChatMessageContent nor a list of ChatMessageContent. The handoff actor caches the initial messages before invoking its agent, and requires the DefaultTypeAlias shape; anything else is rejected.

Source

Thrown at python/semantic_kernel/agents/orchestration/handoffs.py:260

            await self._result_callback(
                ChatMessageContent(
                    role=AuthorRole.ASSISTANT,
                    name=self._agent.name,
                    content=f"Task is completed with summary: {task_summary}",
                )
            )
        self._task_completed = True

    @message_handler
    async def _handle_start_message(self, message: HandoffStartMessage, cts: MessageContext) -> None:
        logger.debug(f"{self.id}: Received handoff start message.")
        if isinstance(message.body, ChatMessageContent):
            self._message_cache.add_message(message.body)
        elif isinstance(message.body, list) and all(isinstance(m, ChatMessageContent) for m in message.body):
            for m in message.body:
                self._message_cache.add_message(m)
        else:
            raise ValueError(f"Invalid message body type: {type(message.body)}. Expected {DefaultTypeAlias}.")

    @message_handler
    async def _handle_response_message(self, message: HandoffResponseMessage, cts: MessageContext) -> None:
        """Handle a response message from an agent in the handoff group."""
        logger.debug(f"{self.id}: Received handoff response message.")
        self._message_cache.add_message(message.body)

    @message_handler
    async def _handle_request_message(self, message: HandoffRequestMessage, cts: MessageContext) -> None:
        """Handle a request message from an agent in the handoff group."""
        if message.agent_name != self._agent.name:
            return
        logger.debug(f"{self.id}: Received handoff request message.")

        response = await self._invoke_agent_with_potentially_no_response(kernel=self._kernel)

        while not self._task_completed:
            if self._handoff_agent_name:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure input_transform returns ChatMessageContent or list[ChatMessageContent].
  2. Wrap raw input strings into ChatMessageContent(role=AuthorRole.USER, content=...) before invoking.
  3. Match the DefaultTypeAlias shape required by the installed SK version.
  4. Do not publish HandoffStartMessage with an arbitrary body type.

Example fix

# before
result = await handoff_orchestration.invoke("please summarize")  # may produce wrong body
# after
result = await handoff_orchestration.invoke(
    [ChatMessageContent(role=AuthorRole.USER, content="please summarize")],
    runtime=runtime,
)
Defensive patterns

Strategy: type-guard

Validate before calling

# Normalize orchestration input to the expected type before invoking:
from semantic_kernel.contents import ChatMessageContent, AuthorRole
def normalize(inp):
    if isinstance(inp, str):
        return [ChatMessageContent(role=AuthorRole.USER, content=inp)]
    return inp

Type guard

from semantic_kernel.contents import ChatMessageContent
def is_valid_body(body) -> bool:
    if isinstance(body, ChatMessageContent):
        return True
    return isinstance(body, list) and all(isinstance(m, ChatMessageContent) for m in body)

Try / catch

try:
    result = await handoff_orchestration.invoke(messages, runtime=runtime)
except ValueError as ex:
    if "Invalid message body type" in str(ex):
        messages = normalize(messages)
        result = await handoff_orchestration.invoke(messages, runtime=runtime)

Prevention

When it happens

Trigger: A HandoffStartMessage is published with a body that is not a ChatMessageContent or list thereof. Stems from a custom input_transform on HandoffOrchestration returning the wrong type, or feeding raw strings/other objects into the orchestration.

Common situations: input_transform returns a raw string/dict instead of ChatMessageContent; passing a string into orchestration.invoke; version drift changing the expected message type; manually constructing a HandoffStartMessage with an invalid body.

Related errors


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