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

{block}

What it means

`convert_to_openai_messages` supports a `"json"` content-block dialect (matched when `block["type"] == "json"` or the block has a top-level `"json"` key), serializing the payload to a text block. If the block sets `type: "json"` but carries no `"json"` key, there is nothing to serialize and the conversion raises. Note the branch order means a `type` of `"json"` without the key is treated as malformed, not passed through.

Source

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

                        block["content"],
                        tool_call_id=block["tool_use_id"],
                        status="error" if block.get("is_error") else "success",
                    )
                    # Recurse to make sure tool message contents are OpenAI format.
                    tool_messages.extend(
                        convert_to_openai_messages(
                            [tool_message], text_format=text_format
                        )
                    )
                elif (block.get("type") == "json") or "json" in block:
                    if "json" not in block:
                        msg = (
                            f"Unrecognized content block at "
                            f"messages[{i}].content[{j}] has 'type': 'json' "
                            f"but does not have a 'json' key. Full "
                            f"content block:\n\n{block}"
                        )
                        raise ValueError(msg)
                    content.append(
                        {
                            "type": "text",
                            "text": json.dumps(block["json"]),
                        }
                    )
                elif (block.get("type") == "guard_content") or "guard_content" in block:
                    if (
                        "guard_content" not in block
                        or "text" not in block["guard_content"]
                    ):
                        msg = (
                            f"Unrecognized content block at "
                            f"messages[{i}].content[{j}] has 'type': "
                            f"'guard_content' but does not have a "
                            f"messages[{i}].content[{j}]['guard_content']['text'] "
                            f"key. Full content block:\n\n{block}"
                        )

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Put the payload under the `json` key: `{"type": "json", "json": {"answer": 42}}`.
  2. If you meant a plain text block, use `{"type": "text", "text": json.dumps(obj)}`.
  3. Rename whatever payload key you currently use (`data`, `value`, `body`) to `json` before conversion.

Example fix

// before
{"type": "json", "data": {"answer": 42}}

// after
{"type": "json", "json": {"answer": 42}}
Defensive patterns

Strategy: validation

Validate before calling

for b in blocks:
    if b.get("type") == "json" and "json" not in b:
        raise ValueError(f"json block without payload: {b}")
    # or repair: b["json"] = b.pop("data", None)

Type guard

def is_json_block(b: dict) -> bool:
    return b.get("type") == "json" and "json" in b

Prevention

When it happens

Trigger: `{"type": "json"}` alone, or `{"type": "json", "data": {...}}` where the payload key is named something other than `json`.

Common situations: Custom message schemas from other frameworks that use `type: "json"` with a differently named payload; template code that sets the type tag but forgets the payload; merging dict fragments that drop falsy values.

Related errors


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