langchain-ai/langchain · error · ValueError

Unrecognized content block at messages[{i}].content[{j}] has

Error message

Unrecognized content block at messages[{i}].content[{j}] has 'type': 'image_url' but is missing expected key(s) {missing}. Full content block:

{block}

What it means

Raised by `convert_to_openai_messages` when a content block declares `'type': 'image_url'` but lacks the nested 'image_url' key. The converter must read `block['image_url']['url']` to build the OpenAI image payload, so the key is mandatory and the full block is echoed in the error.

Source

Thrown at libs/core/langchain_core/messages/utils.py:1707

                elif block.get("type") == "text":
                    if missing := [k for k in ("text",) if k not in block]:
                        err = (
                            f"Unrecognized content block at "
                            f"messages[{i}].content[{j}] has 'type': 'text' "
                            f"but is missing expected key(s) "
                            f"{missing}. Full content block:\n\n{block}"
                        )
                        raise ValueError(err)
                    content.append({"type": block["type"], "text": block["text"]})
                elif block.get("type") == "image_url":
                    if missing := [k for k in ("image_url",) if k not in block]:
                        err = (
                            f"Unrecognized content block at "
                            f"messages[{i}].content[{j}] has 'type': 'image_url' "
                            f"but is missing expected key(s) "
                            f"{missing}. Full content block:\n\n{block}"
                        )
                        raise ValueError(err)
                    content.append(
                        {
                            "type": "image_url",
                            "image_url": block["image_url"],
                        }
                    )
                # Standard multi-modal content block
                elif is_data_content_block(block):
                    formatted_block = convert_to_openai_data_block(block)
                    if (
                        formatted_block.get("type") == "file"
                        and "file" in formatted_block
                        and "filename" not in formatted_block["file"]
                    ):
                        logger.info("Generating a fallback filename.")
                        formatted_block["file"]["filename"] = "LC_AUTOGENERATED"
                    content.append(formatted_block)
                # Anthropic and Bedrock converse format

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Nest the URL: `{'type': 'image_url', 'image_url': {'url': '<url or data URI>'}}`
  2. If starting from base64 data, build a data URI: `f'data:{media_type};base64,{b64}'` inside `image_url.url`
  3. Use the echoed block in the error message to spot the wrong key shape

Example fix

# before
{'type': 'image_url', 'url': 'https://example.com/cat.png'}

# after
{'type': 'image_url', 'image_url': {'url': 'https://example.com/cat.png'}}
Defensive patterns

Strategy: validation

Validate before calling

def valid_image_url_block(b: dict) -> bool:
    return b.get('type') == 'image_url' and isinstance(b.get('image_url'), dict) and 'url' in b['image_url']

# normalize common mistake: flat url
if isinstance(b, dict) and b.get('type') == 'image_url' and 'url' in b and 'image_url' not in b:
    b = {'type': 'image_url', 'image_url': {'url': b['url']}}

Type guard

def is_wellformed_image_url_block(b: object) -> bool:
    return (isinstance(b, dict) and b.get('type') == 'image_url'
            and isinstance(b.get('image_url'), dict) and 'url' in b['image_url'])

Prevention

When it happens

Trigger: A block like `{'type': 'image_url'}` or `{'type': 'image_url', 'url': 'https://...'}` (url placed at the top level instead of nested under 'image_url').

Common situations: Flattened image blocks copied from curl examples; converting Gemini/Anthropic image shapes by hand and forgetting the nesting; the nested dict present but keyed differently.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/48e976212a76dbf4. Report an issue: GitHub.