{"record":{"id":"931468b4b538a282","repo":"langchain-ai/langchain","slug":"unrecognized-content-block-at-messages-i-conten-931468","errorCode":null,"errorMessage":"Unrecognized content block at messages[{i}].content[{j}] has 'type': 'guard_content' but does not have a messages[{i}].content[{j}]['guard_content']['text'] key. Full content block:\n\n{block}","messagePattern":"Unrecognized content block at messages\\[(.+?)\\]\\.content\\[(.+?)\\] has 'type': 'guard_content' but does not have a messages\\[(.+?)\\]\\.content\\[(.+?)\\]\\['guard_content'\\]\\['text'\\] key\\. Full content block:\n\n(.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/messages/utils.py","lineNumber":1911,"sourceCode":"                    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                        )\n                        raise ValueError(msg)\n                    text = block[\"guard_content\"][\"text\"]\n                    if isinstance(text, dict):\n                        text = text[\"text\"]\n                    content.append({\"type\": \"text\", \"text\": text})\n                # VertexAI format\n                elif block.get(\"type\") == \"media\":\n                    if missing := [k for k in (\"mime_type\", \"data\") if k not in block]:\n                        err = (\n                            f\"Unrecognized content block at \"\n                            f\"messages[{i}].content[{j}] has 'type': \"\n                            f\"'media' but does not have key(s) {missing}. Full \"\n                            f\"content block:\\n\\n{block}\"\n                        )\n                        raise ValueError(err)\n                    if \"image\" not in block[\"mime_type\"]:\n                        err = (\n                            f\"OpenAI messages can only support text and image data.\"\n                            f\" Received content block with media of type:\"","sourceCodeStart":1893,"sourceCodeEnd":1929,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/messages/utils.py#L1893-L1929","documentation":"The converter recognizes a `\"guard_content\"` dialect (used for LanGuardian-style guarded text): the block must contain `guard_content` and that nested dict must contain `text` (either a string or `{\"text\": ...}`). If either is missing, the guard text cannot be extracted and the block is rejected with this error. The check fires both when `type == \"guard_content\"` lacks the key entirely and when the nested `text` is absent.","triggerScenarios":"`{\"type\": \"guard_content\"}` with no `guard_content` key; `{\"guard_content\": {\"type\": \"text\"}}` where the nested payload omits `text`; guard blocks produced by a middleware version with a different schema.","commonSituations":"Integrating content-moderation middleware that emits `guard_content` blocks; upgrading the middleware after its schema changed; hand-crafting guard blocks in tests.","solutions":["Emit the full shape: `{\"type\": \"guard_content\", \"guard_content\": {\"type\": \"text\", \"text\": \"...\"}}` (nested `text` as a plain string also works).","If moderation is not needed, remove the block rather than leaving a stub.","Pin/verify the middleware version whose guard-block schema matches what `langchain-core` expects."],"exampleFix":"// before\n{\"type\": \"guard_content\", \"guard_content\": {\"type\": \"text\"}}\n\n// after\n{\"type\": \"guard_content\", \"guard_content\": {\"type\": \"text\", \"text\": \"guarded payload\"}}","handlingStrategy":"validation","validationCode":"def valid_guard_block(b: dict) -> bool:\n    gc = b.get(\"guard_content\")\n    return isinstance(gc, dict) and (\n        isinstance(gc.get(\"text\"), str)\n        or isinstance(gc.get(\"text\"), dict) and \"text\" in gc[\"text\"]\n    )\n\nblocks = [b for b in blocks if b.get(\"type\") != \"guard_content\" or valid_guard_block(b)]","typeGuard":"def is_guard_content_block(b: dict) -> bool:\n    return (\n        (b.get(\"type\") == \"guard_content\" or \"guard_content\" in b)\n        and isinstance(b.get(\"guard_content\"), dict)\n        and \"text\" in b[\"guard_content\"]\n    )","tryCatchPattern":null,"preventionTips":["Pin the moderation middleware version and test its emitted schema","If moderation is disabled, ensure no stub guard blocks remain in history","Cover guard blocks in your message-round-trip tests"],"tags":["messages","content-blocks","guard-content","validation"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}