conductor-oss/conductor · error · IllegalArgumentException
External tool data exceeds the maximum nesting depth of {MAX
Error message
External tool data exceeds the maximum nesting depth of {MAX_NESTING_DEPTH} What it means
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.
Source
Thrown at ai/src/main/java/org/conductoross/conductor/ai/http/ExternalDataLimits.java:42
public static final int MAX_NESTING_DEPTH = 32;
private ExternalDataLimits() {}
/** Rejects object graphs that would make workflow state expensive or unsafe to process. */
public static void validateStructure(Object value) {
validateStructure(value, 0, new IdentityHashMap<>());
}
private static void validateStructure(
Object value, int depth, IdentityHashMap<Object, Boolean> seen) {
if (value == null
|| value instanceof String
|| value instanceof Number
|| value instanceof Boolean) {
return;
}
if (depth > MAX_NESTING_DEPTH) {
throw new IllegalArgumentException(
"External tool data exceeds the maximum nesting depth of " + MAX_NESTING_DEPTH);
}
if (seen.put(value, Boolean.TRUE) != null) {
throw new IllegalArgumentException("External tool data contains a cyclic structure");
}
try {
if (value instanceof Map<?, ?> map) {
for (Map.Entry<?, ?> entry : map.entrySet()) {
validateStructure(entry.getKey(), depth + 1, seen);
validateStructure(entry.getValue(), depth + 1, seen);
}
} else if (value instanceof Collection<?> collection) {
for (Object item : collection) {
validateStructure(item, depth + 1, seen);
}
} else if (value.getClass().isArray()) {
for (int i = 0; i < Array.getLength(value); i++) {
validateStructure(Array.get(value, i), depth + 1, seen);View on GitHub (pinned to cf7c3e4a8a)
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).
Example fix
// before — deeply nested wrapper
Map.of("a", Map.of("b", Map.of("c", ... /* 40 deep */ ...)))
// after — flatten to a shallow map
Map.of("result", flatList, "count", n) Defensive patterns
Strategy: validation
Validate before calling
// Flatten/truncate external data before validation and before writing workflow state // Keep nesting under ExternalDataLimits.MAX_NESTING_DEPTH (32) Object flattened = projectToShallowMap(rawToolResult); ExternalDataLimits.validateStructure(flattened);
Try / catch
try {
ExternalDataLimits.validateStructure(value);
} catch (IllegalArgumentException e) {
// flatten at the source and retry; this is a data-shape problem, not transient
throw new IllegalArgumentException("Tool data too deeply nested; flatten before use", e);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- External tool data contains a cyclic structure
- Execution not found: ${executionId}
- inspectPlan: agentConfig is required
- inspectPlan: plan is required
- inspectPlan: agentConfig.strategy must be 'plan_execute', go
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/7876191fcd2cc644.
Report an issue: GitHub.