ComposioHQ/composio · error · RangeError
Tool arguments exceed maximum nesting depth of ${MAX_NODE_DE
Error message
Tool arguments exceed maximum nesting depth of ${MAX_NODE_DEPTH} What it means
omitNulls walks tool arguments against the schema and throws RangeError when the arguments object nests deeper than MAX_NODE_DEPTH — i.e. the runtime input, not the schema, is pathologically deep.
Source
Thrown at ts/packages/core/src/utils/jsonSchema.ts:952
if (!Array.isArray(branches)) continue;
for (const branch of branches) {
const found = find(branch, depth + 1);
if (found) return found;
}
}
return undefined;
};
return find(resolved, 0) ?? resolved;
}
function omitNulls(
value: unknown,
schema: unknown,
root: Record<string, unknown>,
depth: number
): unknown {
if (depth > MAX_NODE_DEPTH) {
throw new RangeError(`Tool arguments exceed maximum nesting depth of ${MAX_NODE_DEPTH}`);
}
const node = selectBranchFor(schema, value, root);
if (Array.isArray(value)) {
const items = node && isPlainObject(node.items) ? node.items : undefined;
return value.map(item => omitNulls(item, items, root, depth + 1));
}
if (!isPlainObject(value)) return value;
const properties = node && isPlainObject(node.properties) ? node.properties : {};
const clone: Record<string, unknown> = {};
for (const [key, child] of Object.entries(value)) {
const propertySchema = Object.prototype.hasOwnProperty.call(properties, key)
? properties[key]
: undefined;
if (child === null) {
if (propertySchema === undefined || schemaAcceptsNull(propertySchema, root)) {
setOwn(clone, key, child);
}View on GitHub (pinned to 64b1b85502)
Solutions
- Validate/limit argument nesting before execute(); reject payloads deeper than a sane bound.
- JSON.stringify the arguments first — cyclic structures will throw there and reveal the bug.
- Cap LLM output size and nesting when arguments are model-authored.
Example fix
// before
await tool.execute(args);
// after
const depth = (v: unknown, d = 0): number =>
v && typeof v === 'object'
? Math.max(d, ...Object.values(v as object).map(x => depth(x, d + 1)))
: d;
if (depth(args) > 100) throw new Error('arguments too deeply nested');
await tool.execute(args); Defensive patterns
Strategy: validation
Validate before calling
const depth = (v: unknown, d = 0): number =>
v && typeof v === 'object'
? Math.max(d, ...Object.values(v as object).map(x => depth(x, d + 1)))
: d;
if (depth(args) > 100) throw new Error('arguments too deep'); Prevention
- JSON.stringify arguments first to surface cycles.
- Cap nesting of model-generated arguments.
When it happens
Trigger: Executing a tool with arguments containing extremely deep nested objects/arrays (e.g. an LLM-generated payload with runaway recursion), or a self-referencing object that escaped JSON serialization bounds.
Common situations: Untrusted or model-generated tool arguments; clients that build arguments recursively; crafted payloads.
Related errors
- JSON Schema node depth exceeded cap (${MAX_NODE_DEPTH})
- JSON Schema $ref chain exceeded depth cap (${MAX_REF_CHAIN_D
- JSON Schema exceeds maximum nesting depth of ${MAX_NODE_DEPT
- Tool arguments nesting exceeded the maximum supported depth
- JSON Schema node depth exceeded cap ({MAX_NODE_DEPTH})
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/4a38fa6003b312a9.
Report an issue: GitHub.