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' but does not have a 'source' or 'image' key. Full content block:

{block}

What it means

`convert_to_openai_messages` hits this branch when a block declares `"type": "image"` but has neither an Anthropic-style `source` key nor a Bedrock-style `image` key. The converter recognizes two image dialects: Anthropic (`{"type": "image", "source": {...}}`) and Bedrock Converse (`{"type": "image", "image": {...}}`). With neither present it cannot locate the image payload, so it raises rather than emit a broken `image_url` block.

Source

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

                        b64_image = _bytes_to_b64_str(image["source"]["bytes"])
                        content.append(
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": (
                                        f"data:image/{image['format']};base64,{b64_image}"
                                    )
                                },
                            }
                        )
                    else:
                        err = (
                            f"Unrecognized content block at "
                            f"messages[{i}].content[{j}] has 'type': 'image' "
                            f"but does not have a 'source' or 'image' key. Full "
                            f"content block:\n\n{block}"
                        )
                        raise ValueError(err)
                # OpenAI file format
                elif (
                    block.get("type") == "file"
                    and isinstance(block.get("file"), dict)
                    and isinstance(block.get("file", {}).get("file_data"), str)
                ):
                    if block.get("file", {}).get("filename") is None:
                        logger.info("Generating a fallback filename.")
                        formatted_block = {
                            **block,
                            "file": {**block["file"], "filename": "LC_AUTOGENERATED"},
                        }
                        content.append(formatted_block)
                    else:
                        content.append(block)
                # OpenAI audio format
                elif (
                    block.get("type") == "input_audio"

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Use the OpenAI shape: `{"type": "image_url", "image_url": {"url": "..."}}` — do not set `type` to `image`.
  2. Or use Anthropic shape: `{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "<b64>"}}`.
  3. Or use Bedrock shape: `{"type": "image", "image": {"format": ..., "source": {"bytes": ...}}}`.
  4. Search your message-construction code for `"type": "image"` and replace with one of the three canonical shapes above.

Example fix

// before
{"type": "image", "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 is_recognized_image_block(b: dict) -> bool:
    if b.get("type") != "image":
        return True
    return "source" in b or isinstance(b.get("image"), dict)

blocks = [b for b in blocks if is_recognized_image_block(b)]  # or raise early with your own message

Type guard

def is_anthropic_image(b: dict) -> bool:
    return (
        b.get("type") == "image"
        and isinstance(b.get("source"), dict)
        and b["source"].get("type") in {"base64", "url"}
    )

Try / catch

try:
    oai = convert_to_openai_messages(messages)
except ValueError as e:
    # error includes the full offending block; log and reject the input payload
    raise HTTPException(400, "unsupported image block") if serving else None

Prevention

When it happens

Trigger: Blocks like `{"type": "image", "url": "https://..."}` or `{"type": "image", "data": "<b64>"}` — keys the converter does not look for when `type == "image"`. Also image blocks whose payload key was renamed or nested differently by upstream code.

Common situations: Developers assuming OpenAI-style `image_url` goes under `type: "image"`; LLM-generated or user-submitted content blocks with ad-hoc schemas; migrating from frameworks that use `url`/`data` keys for images.

Related errors


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