{"record":{"id":"15ae8948d73bd967","repo":"microsoft/autogen","slug":"image-content-cannot-be-converted-to-text-15ae89","errorCode":null,"errorMessage":"Image content cannot be converted to text","messagePattern":"Image content cannot be converted to text","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/memory/chromadb/_chromadb.py","lineNumber":300,"sourceCode":"                raise\n\n    def _extract_text(self, content_item: str | MemoryContent) -> str:\n        \"\"\"Extract searchable text from content.\"\"\"\n        if isinstance(content_item, str):\n            return content_item\n\n        content = content_item.content\n        mime_type = content_item.mime_type\n\n        if mime_type in [MemoryMimeType.TEXT, MemoryMimeType.MARKDOWN]:\n            return str(content)\n        elif mime_type == MemoryMimeType.JSON:\n            if isinstance(content, dict):\n                # Store original JSON string representation\n                return str(content).lower()\n            raise ValueError(\"JSON content must be a dict\")\n        elif isinstance(content, Image):\n            raise ValueError(\"Image content cannot be converted to text\")\n        else:\n            raise ValueError(f\"Unsupported content type: {mime_type}\")\n\n    def _calculate_score(self, distance: float) -> float:\n        \"\"\"Convert ChromaDB distance to a similarity score.\"\"\"\n        if self._config.distance_metric == \"cosine\":\n            return 1.0 - (distance / 2.0)\n        return 1.0 / (1.0 + distance)\n\n    async def update_context(\n        self,\n        model_context: ChatCompletionContext,\n    ) -> UpdateContextResult:\n        messages = await model_context.get_messages()\n        if not messages:\n            return UpdateContextResult(memories=MemoryQueryResult(results=[]))\n\n        # Extract query from last message","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/memory/chromadb/_chromadb.py#L282-L318","documentation":"ChromaDBVectorMemory stores documents as plain text, so when you add or query with a MemoryContent whose payload is an Image, _extract_text refuses to serialize it and raises ValueError. ChromaDB's embedding pipeline only accepts strings, so image bytes have no representation in this backend. Use a memory backend that supports multimodal content or omit image items.","triggerScenarios":"Calling chroma_memory.add(MemoryContent(content=Image.frompil(img), ...)) or query(MemoryContent(content=Image(...))). Also triggered when a MemoryContent was constructed with mime_type=TEXT but the content is an Image instance (the isinstance(content, Image) check fires before the mime-type fallback).","commonSituations":"Porting an agent from a multimodal context (where messages legitimately contain Image parts) into ChromaDB memory; copying MemoryContent objects straight from a ChatCompletionContext that contains images; filtering only on mime_type instead of the actual payload type.","solutions":["Filter out Image contents before adding to ChromaDBVectorMemory: check isinstance(content, Image) (or content is not str/dict) and skip or store a text caption instead.","If you need image memory, use a different Memory implementation or persist a textual description (e.g. an LLM-generated caption) as MemoryMimeType.TEXT.","If you expected text, verify you did not wrap the string in Image accidentally and that mime_type matches the payload type."],"exampleFix":"// before\nawait memory.add(MemoryContent(content=Image.from_pil(img), mime_type=MemoryMimeType.IMAGE))\n\n// after\nif isinstance(content, Image):\n    caption = await describe_image(content)  # text fallback\n    await memory.add(MemoryContent(content=caption, mime_type=MemoryMimeType.TEXT))\nelse:\n    await memory.add(MemoryContent(content=content, mime_type=MemoryMimeType.TEXT))","handlingStrategy":"type-guard","validationCode":"from autogen_core.memory import MemoryContent, MemoryMimeType\nfrom autogen_core import Image\n\ndef is_text_storable(item: MemoryContent) -> bool:\n    return not isinstance(item.content, Image)","typeGuard":"def is_image_content(item: MemoryContent) -> bool:\n    return isinstance(item.content, Image)","tryCatchPattern":"try:\n    await memory.add(item)\nexcept ValueError as e:\n    if 'Image content' in str(e):\n        logger.warning('skipping image memory item')\n    else:\n        raise","preventionTips":["Filter isinstance(content, Image) before every add() to ChromaDBVectorMemory","Store text captions for multimodal items instead of raw images","Keep one content-normalization helper for all memory writes"],"tags":["chromadb","memory","multimodal","validation"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}