{"record":{"id":"7c834a7d9aa9992f","repo":"BerriAI/litellm","slug":"content-blocked-mcp-tool-result-structuredcontent","errorCode":null,"errorMessage":"Content blocked: MCP tool result structuredContent is nested too deeply to be scanned by the configured guardrail","messagePattern":"Content blocked: MCP tool result structuredContent is nested too deeply to be scanned by the configured guardrail","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py","lineNumber":133,"sourceCode":"        ``structuredContent`` is scanned and masked too, in the same\n        ``apply_guardrail`` call: it is serialized to the client alongside\n        ``content``, so a value living only there would otherwise reach the\n        client unscanned.\n        \"\"\"\n        content: Final = mcp_tool_result_content_list(response)\n        text_blocks: Final = (\n            tuple(\n                (index, text) for index, item in enumerate(content) if (text := mcp_content_item_text(item)) is not None\n            )\n            if content is not None\n            else ()\n        )\n\n        structured: Final = mcp_tool_result_structured_content(response)\n        structured_leaves: Final = json_string_leaves(structured) if structured is not None else ()\n        structured_labels: Final = json_unrewritable_labels(structured) if structured is not None else ()\n        if structured_leaves is None or structured_labels is None:\n            raise HTTPException(\n                status_code=400,\n                detail={\n                    \"error\": (\n                        \"Content blocked: MCP tool result structuredContent is nested too deeply to be scanned \"\n                        \"by the configured guardrail\"\n                    )\n                },\n            )\n\n        if not text_blocks and not structured_leaves and not structured_labels:\n            verbose_proxy_logger.debug(\"MCP Guardrail: tool result has no scannable text, nothing to do\")\n            return response\n\n        originals: Final = (\n            tuple(text for _, text in text_blocks) + tuple(text for _, text in structured_leaves) + structured_labels\n        )\n        guardrailed_inputs: Final = await guardrail_to_apply.apply_guardrail(\n            inputs=GenericGuardrailAPIInputs(texts=list(originals)),","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py#L115-L151","documentation":"The guardrail scanner hit its nesting-depth ceiling while serializing an MCP tool result's structuredContent for scanning. Rather than letting unscannable content reach the client, the request is blocked — a safety cutoff, not a data bug.","triggerScenarios":"Thrown at litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py:133 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Reduce nesting depth of structuredContent, or raise the guardrail scan depth limit."],"exampleFix":"Flatten structuredContent or configure a deeper scan limit.","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}