{"record":{"id":"9d56e9f811ba2904","repo":"mem0ai/mem0","slug":"image-url-content-part-is-missing-image-url-url-9d56e9","errorCode":null,"errorMessage":"image_url content part is missing image_url.url","messagePattern":"image_url content part is missing image_url\\.url","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/memory/utils.py","lineNumber":214,"sourceCode":"        if isinstance(content, list):\n            if llm is None:\n                text_parts = [\n                    part[\"text\"] for part in msg[\"content\"]\n                    if isinstance(part, dict) and part.get(\"type\") == \"text\"\n                ]\n                if not text_parts:\n                    continue\n                returned_messages.append({\"role\": role, \"content\": \" \".join(text_parts)})\n            else:\n                description = get_image_description(msg, llm, vision_details)\n                returned_messages.append({\"role\": role, \"content\": description})\n        elif isinstance(content, dict) and content.get(\"type\") == \"image_url\":\n            if llm is None:\n                continue\n            image_url_obj = content.get(\"image_url\")\n            image_url = image_url_obj.get(\"url\") if isinstance(image_url_obj, dict) else None\n            if not image_url:\n                raise ValueError(\"image_url content part is missing image_url.url\")\n            try:\n                description = get_image_description(image_url, llm, vision_details)\n                returned_messages.append({\"role\": role, \"content\": description})\n            except Exception as e:\n                raise Exception(f\"Error while downloading {image_url}.\") from e\n        else:\n            # Regular text content\n            returned_messages.append(msg)\n\n    return returned_messages\n\n\ndef process_telemetry_filters(filters):\n    \"\"\"\n    Process the telemetry filters\n    \"\"\"\n    if filters is None:\n        return [], {}","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/memory/utils.py#L196-L232","documentation":"Raised while Mem0 preprocesses multimodal messages: a content part declares type 'image_url' but its image_url field is missing or has no usable url key (image_url is not a dict, or its url is empty/None). The library needs the URL to download and describe the image via the vision LLM, so it refuses the malformed part instead of passing a broken payload downstream.","triggerScenarios":"Passing messages with {'type': 'image_url', 'image_url': {}} or {'type': 'image_url'} (no image_url key); image_url given as a plain string instead of {'url': ...}; OpenAI-style payloads assembled by hand or by a client that omits url for placeholders/base64 edge cases; a vision LLM must also be configured (llm is not None) or the part is skipped, not raised.","commonSituations":"Hand-built multimodal prompts where the image_url wrapper object is forgotten; adapters converting between message formats (Anthropic/OpenAI/Gemini) dropping or flattening the url field; LLM-generated tool output inserted as message content with a malformed image part.","solutions":["Format image parts exactly as {'type': 'image_url', 'image_url': {'url': '<https://... or data:...>'}}","Validate/normalize your message list before passing it to memory.add/search (see typeGuard below)","If images are optional in your pipeline, strip malformed image parts instead of forwarding them"],"exampleFix":"# before\nmessages = [{\"role\": \"user\", \"content\": [{\"type\": \"image_url\", \"image_url\": {}}]}]\nawait memory.add(messages, user_id=\"alice\")\n\n# after\nmessages = [{\"role\": \"user\", \"content\": [{\"type\": \"image_url\", \"image_url\": {\"url\": \"https://example.com/cat.png\"}}]}]\nawait memory.add(messages, user_id=\"alice\")","handlingStrategy":"type-guard","validationCode":"def valid_image_parts(messages):\n    for m in messages:\n        content = m.get(\"content\")\n        if isinstance(content, list):\n            for part in content:\n                if isinstance(part, dict) and part.get(\"type\") == \"image_url\":\n                    iu = part.get(\"image_url\")\n                    assert isinstance(iu, dict) and iu.get(\"url\"), f\"malformed image part: {part}\"\n    return messages","typeGuard":"def is_valid_image_part(part) -> bool:\n    return (\n        isinstance(part, dict)\n        and part.get(\"type\") == \"image_url\"\n        and isinstance(part.get(\"image_url\"), dict)\n        and isinstance(part[\"image_url\"].get(\"url\"), str)\n        and len(part[\"image_url\"][\"url\"]) > 0\n    )","tryCatchPattern":null,"preventionTips":["Use provider-standard message builders instead of hand-writing multimodal parts","Sanitize LLM/tool-generated content before forwarding into memory.add()","Add schema validation at your API boundary for inbound messages"],"tags":["multimodal","vision","message-format","validation"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}