{"record":{"id":"df5970d2e1c7065e","repo":"microsoft/autogen","slug":"unknown-content-part-part","errorCode":null,"errorMessage":"Unknown content part: {part}","messagePattern":"Unknown content part: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/models/openai/_message_transform.py","lineNumber":239,"sourceCode":"\ndef _set_multimodal_content(\n    message: LLMMessage, context: Dict[str, Any]\n) -> Dict[str, List[ChatCompletionContentPartParam]]:\n    assert isinstance(message, (UserMessage, AssistantMessage))\n    prepend = context.get(\"prepend_name\", False)\n    parts: List[ChatCompletionContentPartParam] = []\n\n    for idx, part in enumerate(message.content):\n        if isinstance(part, str):\n            # If prepend, Append the name to the first text part\n            text = f\"{message.source} said:\\n\" + part if prepend and idx == 0 else part\n            parts.append(ChatCompletionContentPartTextParam(type=\"text\", text=text))\n        elif isinstance(part, Image):\n            # TODO: support url based images\n            # TODO: support specifying details\n            parts.append(cast(ChatCompletionContentPartImageParam, part.to_openai_format()))\n        else:\n            raise ValueError(f\"Unknown content part: {part}\")\n\n    return {\"content\": parts}\n\n\ndef _set_tool_calls(\n    message: LLMMessage, context: Dict[str, Any]\n) -> Dict[str, List[ChatCompletionMessageToolCallParam]]:\n    assert isinstance(message.content, list)\n    assert isinstance(message, AssistantMessage)\n    return {\n        \"tool_calls\": [func_call_to_oai(x) for x in message.content],\n    }\n\n\ndef _set_thought_as_content(message: LLMMessage, context: Dict[str, Any]) -> Dict[str, str | None]:\n    assert isinstance(message, AssistantMessage)\n    return {\"content\": message.thought}\n","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/openai/_message_transform.py#L221-L257","documentation":"When converting an autogen multimodal UserMessage to OpenAI's content-part format, _message_transform.py accepts only str and Image parts. Any other object type in message.content (which is typed List[str | Image] but Python does not enforce it at runtime) raises ValueError('Unknown content part: {part}'). The transformer deliberately rejects unknown part types rather than guessing a serialization.","triggerScenarios":"Passing a UserMessage whose content list contains anything besides str or Image instances — e.g. a dict {'type':'text','text':'hi'}, a MultiModalContent object from a newer autogen version, a PIL image, or a custom class. Reached via create()/create_stream() on OpenAI-compatible clients that use the shared transformer.","commonSituations":"Mixing autogen-core versions where a newer content type (e.g. MultiModalContent) is produced by one package but an older autogen-ext transformer doesn't know it; hand-building message content with raw OpenAI dicts instead of autogen types; putting a URL string/object where an Image is expected.","solutions":["Use only str and autogen_core.models.Image parts in UserMessage.content lists","Wrap non-string data explicitly: load images via Image.from_file()/Image.from_base64() instead of passing PIL objects or dicts","Align autogen-core and autogen-ext versions (pip install -U autogen-core autogen-ext) so content types and transformers agree"],"exampleFix":"# before\nUserMessage(source='user', content=['look', {'type':'image_url','image_url':{'url':'data:image/png;base64,...'}}])\n# ValueError: Unknown content part: {...}\n\n# after\nfrom autogen_core.models import UserMessage, Image\nUserMessage(source='user', content=['look', Image.from_base64('image/png', base64_data)])","handlingStrategy":"type-guard","validationCode":"from autogen_core.models import UserMessage, Image\n\ndef content_parts_valid(msg) -> bool:\n    if not (isinstance(msg, UserMessage) and isinstance(msg.content, list)):\n        return True\n    return all(isinstance(p, (str, Image)) for p in msg.content)\n\nassert all(content_parts_valid(m) for m in messages)","typeGuard":"from typing import Any\n\ndef is_valid_content_part(part: Any) -> bool:\n    return isinstance(part, (str, Image))","tryCatchPattern":"try:\n    result = await client.create(messages)\nexcept ValueError as e:\n    if 'Unknown content part' in str(e):\n        messages = [normalize_parts(m) for m in messages]  # map dicts/PIL -> str|Image\n        result = await client.create(messages)\n    else:\n        raise","preventionTips":["Only use str and autogen_core Image in multimodal content","Load images via Image.from_file / Image.from_base64, never PIL or dicts","Keep autogen-core and autogen-ext versions in lockstep"],"tags":["openai","multimodal","message-transform","validation","autogen"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}