{"record":{"id":"a9c1289b5ed809a1","repo":"langchain-ai/langchain","slug":"unrecognized-content-block-at-messages-i-conten-a9c128","errorCode":null,"errorMessage":"Unrecognized content block at messages[{i}].content[{j}] has 'type': 'json' but does not have a 'json' key. Full content block:\n\n{block}","messagePattern":"Unrecognized content block at messages\\[(.+?)\\]\\.content\\[(.+?)\\] has 'type': 'json' but does not have a 'json' key\\. Full content block:\n\n(.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/messages/utils.py","lineNumber":1892,"sourceCode":"                        block[\"content\"],\n                        tool_call_id=block[\"tool_use_id\"],\n                        status=\"error\" if block.get(\"is_error\") else \"success\",\n                    )\n                    # Recurse to make sure tool message contents are OpenAI format.\n                    tool_messages.extend(\n                        convert_to_openai_messages(\n                            [tool_message], text_format=text_format\n                        )\n                    )\n                elif (block.get(\"type\") == \"json\") or \"json\" in block:\n                    if \"json\" not in block:\n                        msg = (\n                            f\"Unrecognized content block at \"\n                            f\"messages[{i}].content[{j}] has 'type': 'json' \"\n                            f\"but does not have a 'json' key. Full \"\n                            f\"content block:\\n\\n{block}\"\n                        )\n                        raise ValueError(msg)\n                    content.append(\n                        {\n                            \"type\": \"text\",\n                            \"text\": json.dumps(block[\"json\"]),\n                        }\n                    )\n                elif (block.get(\"type\") == \"guard_content\") or \"guard_content\" in block:\n                    if (\n                        \"guard_content\" not in block\n                        or \"text\" not in block[\"guard_content\"]\n                    ):\n                        msg = (\n                            f\"Unrecognized content block at \"\n                            f\"messages[{i}].content[{j}] has 'type': \"\n                            f\"'guard_content' but does not have a \"\n                            f\"messages[{i}].content[{j}]['guard_content']['text'] \"\n                            f\"key. Full content block:\\n\\n{block}\"\n                        )","sourceCodeStart":1874,"sourceCodeEnd":1910,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/messages/utils.py#L1874-L1910","documentation":"`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.","triggerScenarios":"`{\"type\": \"json\"}` alone, or `{\"type\": \"json\", \"data\": {...}}` where the payload key is named something other than `json`.","commonSituations":"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.","solutions":["Put the payload under the `json` key: `{\"type\": \"json\", \"json\": {\"answer\": 42}}`.","If you meant a plain text block, use `{\"type\": \"text\", \"text\": json.dumps(obj)}`.","Rename whatever payload key you currently use (`data`, `value`, `body`) to `json` before conversion."],"exampleFix":"// before\n{\"type\": \"json\", \"data\": {\"answer\": 42}}\n\n// after\n{\"type\": \"json\", \"json\": {\"answer\": 42}}","handlingStrategy":"validation","validationCode":"for b in blocks:\n    if b.get(\"type\") == \"json\" and \"json\" not in b:\n        raise ValueError(f\"json block without payload: {b}\")\n    # or repair: b[\"json\"] = b.pop(\"data\", None)","typeGuard":"def is_json_block(b: dict) -> bool:\n    return b.get(\"type\") == \"json\" and \"json\" in b","tryCatchPattern":null,"preventionTips":["Name the payload key exactly 'json' in any type:'json' block","Prefer plain text blocks with json.dumps if the json dialect is not required","Add contract tests for custom block schemas"],"tags":["messages","content-blocks","json","validation"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}