microsoft/autogen · error · ValueError

Unsupported message type: {type(msg)}

Error message

Unsupported message type: {type(msg)}

What it means

During create(), any message that is not SystemMessage/UserMessage/AssistantMessage falls into the final else and raises 'Unsupported message type: {type(msg)}'. The client deliberately rejects function/tool result messages (FunctionExecutionResultMessage) and any custom LLMMessage subclass, because it has no conversion path for them.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/_llama_cpp_completion_client.py:298

            | ChatCompletionRequestUserMessage
            | ChatCompletionRequestAssistantMessage
            | ChatCompletionRequestUserMessage
            | ChatCompletionRequestToolMessage
            | ChatCompletionRequestFunctionMessage
        ] = []
        for msg in messages:
            if isinstance(msg, SystemMessage):
                converted_messages.append({"role": "system", "content": msg.content})
            elif isinstance(msg, UserMessage) and isinstance(msg.content, str):
                converted_messages.append({"role": "user", "content": msg.content})
            elif isinstance(msg, AssistantMessage) and isinstance(msg.content, str):
                converted_messages.append({"role": "assistant", "content": msg.content})
            elif (
                isinstance(msg, SystemMessage) or isinstance(msg, UserMessage) or isinstance(msg, AssistantMessage)
            ) and isinstance(msg.content, list):
                raise ValueError("Multi-part messages such as those containing images are currently not supported.")
            else:
                raise ValueError(f"Unsupported message type: {type(msg)}")

        if isinstance(json_output, type) and issubclass(json_output, BaseModel):
            create_args["response_format"] = {"type": "json_object", "schema": json_output.model_json_schema()}
        elif json_output is True:
            create_args["response_format"] = {"type": "json_object"}
        elif json_output is not False and json_output is not None:
            raise ValueError("json_output must be a boolean, a BaseModel subclass or None.")

        # Handle tool_choice parameter
        if tool_choice != "auto":
            warnings.warn(
                "tool_choice parameter is specified but LlamaCppChatCompletionClient does not support it. "
                "This parameter will be ignored.",
                UserWarning,
                stacklevel=2,
            )

        if self.model_info["function_calling"]:

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Filter history to only System/User/Assistant string-content messages before calling create(): [m for m in messages if isinstance(m, (SystemMessage, UserMessage, AssistantMessage))]
  2. Convert FunctionExecutionResultMessage entries into UserMessage(content=str(result.content), source='user') if the model needs the tool output as text
  3. Check the printed type in the message — it names the exact class that slipped through; fix that producer

Example fix

# before
history.append(FunctionExecutionResultMessage(content=[FunctionExecutionResult(content="42", call_id="1")], source="tool"))
await client.create(history)

# after
text_history = [m for m in history if isinstance(m, (SystemMessage, UserMessage, AssistantMessage))]
await client.create(text_history)
Defensive patterns

Strategy: type-guard

Validate before calling

SUPPORTED = (SystemMessage, UserMessage, AssistantMessage)
if not all(isinstance(m, SUPPORTED) for m in messages):
    messages = [m for m in messages if isinstance(m, SUPPORTED)]

Type guard

from autogen_core.models import LLMMessage, SystemMessage, UserMessage, AssistantMessage

def is_supported_message(msg: object) -> TypeGuard[SystemMessage | UserMessage | AssistantMessage]:
    return isinstance(msg, (SystemMessage, UserMessage, AssistantMessage))

Try / catch

try:
    result = await client.create(messages)
except ValueError as e:
    if "Unsupported message type" in str(e):
        messages = [m for m in messages if is_supported_message(m)]
        result = await client.create(messages)
    else:
        raise

Prevention

When it happens

Trigger: Passing FunctionExecutionResultMessage back into create() (common in tool-calling loops that reuse the full history); passing GetToolContentMessage or other autogen-ext message types; passing a custom class subclassing LLMMessage; passing None or a raw dict instead of an LLMMessage.

Common situations: Replaying an entire conversation history — including tool results — from a RoundRobinGroupChat or AssistantAgent transcript into this client; migrating from ReplayChatAgent or an agent-chat serialization format that includes tool-result entries.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/cc247c7996c2097f. Report an issue: GitHub.