{"record":{"id":"7876191fcd2cc644","repo":"conductor-oss/conductor","slug":"external-tool-data-exceeds-the-maximum-nesting-dep","errorCode":null,"errorMessage":"External tool data exceeds the maximum nesting depth of {MAX_NESTING_DEPTH}","messagePattern":"External tool data exceeds the maximum nesting depth of (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/http/ExternalDataLimits.java","lineNumber":42,"sourceCode":"    public static final int MAX_NESTING_DEPTH = 32;\n\n    private ExternalDataLimits() {}\n\n    /** Rejects object graphs that would make workflow state expensive or unsafe to process. */\n    public static void validateStructure(Object value) {\n        validateStructure(value, 0, new IdentityHashMap<>());\n    }\n\n    private static void validateStructure(\n            Object value, int depth, IdentityHashMap<Object, Boolean> seen) {\n        if (value == null\n                || value instanceof String\n                || value instanceof Number\n                || value instanceof Boolean) {\n            return;\n        }\n        if (depth > MAX_NESTING_DEPTH) {\n            throw new IllegalArgumentException(\n                    \"External tool data exceeds the maximum nesting depth of \" + MAX_NESTING_DEPTH);\n        }\n        if (seen.put(value, Boolean.TRUE) != null) {\n            throw new IllegalArgumentException(\"External tool data contains a cyclic structure\");\n        }\n        try {\n            if (value instanceof Map<?, ?> map) {\n                for (Map.Entry<?, ?> entry : map.entrySet()) {\n                    validateStructure(entry.getKey(), depth + 1, seen);\n                    validateStructure(entry.getValue(), depth + 1, seen);\n                }\n            } else if (value instanceof Collection<?> collection) {\n                for (Object item : collection) {\n                    validateStructure(item, depth + 1, seen);\n                }\n            } else if (value.getClass().isArray()) {\n                for (int i = 0; i < Array.getLength(value); i++) {\n                    validateStructure(Array.get(value, i), depth + 1, seen);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/http/ExternalDataLimits.java#L24-L60","documentation":"Thrown by ExternalDataLimits.validateStructure when recursion depth exceeds MAX_NESTING_DEPTH (32). ExternalDataLimits bounds untrusted tool/external data before it is copied into durable workflow state; deeply nested JSON (maps/collections/arrays within maps/...) beyond 32 levels is rejected as too expensive/unsafe to persist and process. IllegalArgumentException.","triggerScenarios":"An external tool returns a payload (or a tool-result Map/Collection) whose nesting depth is greater than 32 before validateStructure is called. Each Map entry and Collection element increments depth.","commonSituations":"A third-party API returns a very deep JSON document; a tool wraps results in many layers; accidentally self-referential-but-not-cyclic structures (e.g. deeply nested wrappers); version change in an upstream API that added nesting.","solutions":["Flatten/transform the external payload before passing it to the validator/workflow (pull only the fields you need, collapse wrapper layers).","If deeper nesting is legitimate, the constant MAX_NESTING_DEPTH is a public field (32) — confirm you are within it; there is no per-call override, so flatten at the source.","For tool outputs you control, return a shallow structure (a single object with fields rather than nested envelopes)."],"exampleFix":"// before — deeply nested wrapper\nMap.of(\"a\", Map.of(\"b\", Map.of(\"c\", ... /* 40 deep */ ...)))\n// after — flatten to a shallow map\nMap.of(\"result\", flatList, \"count\", n)","handlingStrategy":"validation","validationCode":"// Flatten/truncate external data before validation and before writing workflow state\n// Keep nesting under ExternalDataLimits.MAX_NESTING_DEPTH (32)\nObject flattened = projectToShallowMap(rawToolResult);\nExternalDataLimits.validateStructure(flattened);","typeGuard":null,"tryCatchPattern":"try {\n    ExternalDataLimits.validateStructure(value);\n} catch (IllegalArgumentException e) {\n    // flatten at the source and retry; this is a data-shape problem, not transient\n    throw new IllegalArgumentException(\"Tool data too deeply nested; flatten before use\", e);\n}","preventionTips":["Project external/tool outputs to a shallow shape before persisting to workflow state.","Return a single object with flat fields from tools you control.","Treat depth > 32 as a smell that an upstream API changed its shape."],"tags":["validation","data-limits","external-data","illegalargument","workflow-state"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}