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 formatView on GitHub (pinned to e32fa9a52e)
Solutions
- Nest the URL: `{'type': 'image_url', 'image_url': {'url': '<url or data URI>'}}`
- If starting from base64 data, build a data URI: `f'data:{media_type};base64,{b64}'` inside `image_url.url`
- 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
- Always nest the URL under the 'image_url' key
- Wrap base64 images as data URIs: f'data:{media_type};base64,{data}'
- Copy the exact block shape from the OpenAI multimodal docs
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
- Unrecognized content block at messages[{i}].content[{j}] has
- Unrecognized content block at messages[{i}].content[{j}] has
- mime_type key is required for base64 data.
- Unsupported source type. Only 'url' and 'base64' are support
- Keys base64, url, or file_id required for file blocks.
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/48e976212a76dbf4.
Report an issue: GitHub.