mem0ai/mem0 · error · ValueError

image_url content part is missing image_url.url

Error message

image_url content part is missing image_url.url

What it means

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.

Source

Thrown at mem0/memory/utils.py:214

        if isinstance(content, list):
            if llm is None:
                text_parts = [
                    part["text"] for part in msg["content"]
                    if isinstance(part, dict) and part.get("type") == "text"
                ]
                if not text_parts:
                    continue
                returned_messages.append({"role": role, "content": " ".join(text_parts)})
            else:
                description = get_image_description(msg, llm, vision_details)
                returned_messages.append({"role": role, "content": description})
        elif isinstance(content, dict) and content.get("type") == "image_url":
            if llm is None:
                continue
            image_url_obj = content.get("image_url")
            image_url = image_url_obj.get("url") if isinstance(image_url_obj, dict) else None
            if not image_url:
                raise ValueError("image_url content part is missing image_url.url")
            try:
                description = get_image_description(image_url, llm, vision_details)
                returned_messages.append({"role": role, "content": description})
            except Exception as e:
                raise Exception(f"Error while downloading {image_url}.") from e
        else:
            # Regular text content
            returned_messages.append(msg)

    return returned_messages


def process_telemetry_filters(filters):
    """
    Process the telemetry filters
    """
    if filters is None:
        return [], {}

View on GitHub (pinned to 001c235229)

Solutions

  1. Format image parts exactly as {'type': 'image_url', 'image_url': {'url': '<https://... or data:...>'}}
  2. Validate/normalize your message list before passing it to memory.add/search (see typeGuard below)
  3. If images are optional in your pipeline, strip malformed image parts instead of forwarding them

Example fix

# before
messages = [{"role": "user", "content": [{"type": "image_url", "image_url": {}}]}]
await memory.add(messages, user_id="alice")

# after
messages = [{"role": "user", "content": [{"type": "image_url", "image_url": {"url": "https://example.com/cat.png"}}]}]
await memory.add(messages, user_id="alice")
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_image_parts(messages):
    for m in messages:
        content = m.get("content")
        if isinstance(content, list):
            for part in content:
                if isinstance(part, dict) and part.get("type") == "image_url":
                    iu = part.get("image_url")
                    assert isinstance(iu, dict) and iu.get("url"), f"malformed image part: {part}"
    return messages

Type guard

def is_valid_image_part(part) -> bool:
    return (
        isinstance(part, dict)
        and part.get("type") == "image_url"
        and isinstance(part.get("image_url"), dict)
        and isinstance(part["image_url"].get("url"), str)
        and len(part["image_url"]["url"]) > 0
    )

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/9d56e9f811ba2904. Report an issue: GitHub.