{"record":{"id":"b80b9e86032ccd3a","repo":"microsoft/autogen","slug":"multi-part-messages-such-as-those-containing-image","errorCode":null,"errorMessage":"Multi-part messages such as those containing images are currently not supported.","messagePattern":"Multi-part messages such as those containing images are currently not supported\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/_llama_cpp_completion_client.py","lineNumber":296,"sourceCode":"        converted_messages: list[\n            ChatCompletionRequestSystemMessage\n            | ChatCompletionRequestUserMessage\n            | ChatCompletionRequestAssistantMessage\n            | ChatCompletionRequestUserMessage\n            | ChatCompletionRequestToolMessage\n            | ChatCompletionRequestFunctionMessage\n        ] = []\n        for msg in messages:\n            if isinstance(msg, SystemMessage):\n                converted_messages.append({\"role\": \"system\", \"content\": msg.content})\n            elif isinstance(msg, UserMessage) and isinstance(msg.content, str):\n                converted_messages.append({\"role\": \"user\", \"content\": msg.content})\n            elif isinstance(msg, AssistantMessage) and isinstance(msg.content, str):\n                converted_messages.append({\"role\": \"assistant\", \"content\": msg.content})\n            elif (\n                isinstance(msg, SystemMessage) or isinstance(msg, UserMessage) or isinstance(msg, AssistantMessage)\n            ) and isinstance(msg.content, list):\n                raise ValueError(\"Multi-part messages such as those containing images are currently not supported.\")\n            else:\n                raise ValueError(f\"Unsupported message type: {type(msg)}\")\n\n        if isinstance(json_output, type) and issubclass(json_output, BaseModel):\n            create_args[\"response_format\"] = {\"type\": \"json_object\", \"schema\": json_output.model_json_schema()}\n        elif json_output is True:\n            create_args[\"response_format\"] = {\"type\": \"json_object\"}\n        elif json_output is not False and json_output is not None:\n            raise ValueError(\"json_output must be a boolean, a BaseModel subclass or None.\")\n\n        # Handle tool_choice parameter\n        if tool_choice != \"auto\":\n            warnings.warn(\n                \"tool_choice parameter is specified but LlamaCppChatCompletionClient does not support it. \"\n                \"This parameter will be ignored.\",\n                UserWarning,\n                stacklevel=2,\n            )","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/_llama_cpp_completion_client.py#L278-L314","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send only string content: UserMessage(content='Describe this', source='user')","Move vision work to a client that supports images (e.g. OpenAIChatCompletionClient with a vision model) and keep llama.cpp for text-only turns","Pre-strip non-text parts before calling create() if the pipeline must stay on llama.cpp"],"exampleFix":"# before\nmessages = [UserMessage(content=[\"Describe\", Image.from_file(\"cat.png\")], source=\"user\")]\nresult = await client.create(messages)\n\n# after\nmessages = [UserMessage(content=\"Describe the image you were shown earlier.\", source=\"user\")]\nresult = await client.create(messages)","handlingStrategy":"validation","validationCode":"def is_text_only(messages: Sequence[LLMMessage]) -> bool:\n    return all(\n        isinstance(m, (SystemMessage, UserMessage, AssistantMessage)) and isinstance(m.content, str)\n        for m in messages\n    )\n\nif not is_text_only(messages):\n    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]","typeGuard":"def has_multipart_content(messages: Sequence[LLMMessage]) -> bool:\n    return any(isinstance(m.content, list) for m in messages if hasattr(m, \"content\"))","tryCatchPattern":"try:\n    result = await client.create(messages)\nexcept ValueError as e:\n    if \"Multi-part\" in str(e):\n        messages = to_text_only(messages)  # your flattening helper\n        result = await client.create(messages)\n    else:\n        raise","preventionTips":["Route image-bearing conversations to a vision-capable client from the start","In shared agent code, branch on client.capabilities['vision'] before attaching Image parts","Keep a text-only serialization of every multimodal message for local-model fallbacks"],"tags":["llama-cpp","multimodal","vision","messages"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}