microsoft/autogen · error · ValueError

Multi-part messages such as those containing images are curr

Error message

Multi-part messages such as those containing images are currently not supported.

What it means

The llama.cpp chat client only converts System/User/Assistant messages whose content is a plain string. If content is a list (the multi-modal shape, e.g. text plus Image parts), the client raises this ValueError because llama-cpp-python message conversion here has no image support. It fires inside create() while building converted_messages.

Source

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

        converted_messages: list[
            ChatCompletionRequestSystemMessage
            | 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,
            )

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Send only string content: UserMessage(content='Describe this', source='user')
  2. Move vision work to a client that supports images (e.g. OpenAIChatCompletionClient with a vision model) and keep llama.cpp for text-only turns
  3. Pre-strip non-text parts before calling create() if the pipeline must stay on llama.cpp

Example fix

# before
messages = [UserMessage(content=["Describe", Image.from_file("cat.png")], source="user")]
result = await client.create(messages)

# after
messages = [UserMessage(content="Describe the image you were shown earlier.", source="user")]
result = await client.create(messages)
Defensive patterns

Strategy: validation

Validate before calling

def is_text_only(messages: Sequence[LLMMessage]) -> bool:
    return all(
        isinstance(m, (SystemMessage, UserMessage, AssistantMessage)) and isinstance(m.content, str)
        for m in messages
    )

if not is_text_only(messages):
    messages = [m.model_copy(update={"content": " ".join(p for p in m.content if isinstance(p, str))}) if isinstance(m.content, list) else m for m in messages]

Type guard

def has_multipart_content(messages: Sequence[LLMMessage]) -> bool:
    return any(isinstance(m.content, list) for m in messages if hasattr(m, "content"))

Try / catch

try:
    result = await client.create(messages)
except ValueError as e:
    if "Multi-part" in str(e):
        messages = to_text_only(messages)  # your flattening helper
        result = await client.create(messages)
    else:
        raise

Prevention

When it happens

Trigger: Calling create([UserMessage(content=['Describe this', Image.from_file('x.png')], source='user')]) on LlamaCppChatCompletionClient; any SystemMessage/AssistantMessage/UserMessage whose content is a list; reusing a vision-oriented agent prompt graph with this client.

Common situations: Porting a multi-modal pipeline from OpenAI/Anthropic clients (which accept list content) to the local llama.cpp client; agent teams where a different participant emits Image parts; tests that build list-content messages generically for all clients.

Related errors


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