{"record":{"id":"1cbd1f0c877c0b33","repo":"ComposioHQ/composio","slug":"tool-arguments-nesting-exceeded-the-maximum-suppor","errorCode":null,"errorMessage":"Tool arguments nesting exceeded the maximum supported depth (${MAX_SCHEMA_DEPTH})","messagePattern":"Tool arguments nesting exceeded the maximum supported depth \\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ts/packages/core/src/utils/schemaPropertyKeys.ts","lineNumber":393,"sourceCode":" */\nexport function sanitizeSchemaPropertyKeys<T extends Record<string, unknown>>(\n  schema: T,\n  policy: KeySanitizationPolicy\n): { schema: T; mapping: KeyMapping } {\n  const { node, mapping } = sanitizeNode(schema, policy);\n  return { schema: node as T, mapping };\n}\n\n/**\n * Restores original property names in a tool-call argument object using the\n * mapping produced by {@link sanitizeSchemaPropertyKeys}. The mapping is walked\n * in lockstep with the value, so a key is only renamed at the nesting level where\n * its alias was actually generated. Nested objects and arrays are handled\n * recursively. Returns a new value; the input is not mutated.\n */\nexport function restoreOriginalKeys(value: unknown, mapping: KeyMapping, depth = 0): unknown {\n  if (depth >= MAX_SCHEMA_DEPTH) {\n    throw new Error(\n      `Tool arguments nesting exceeded the maximum supported depth (${MAX_SCHEMA_DEPTH})`\n    );\n  }\n\n  if (Array.isArray(value)) {\n    const { items, restItems } = mapping;\n    if (Array.isArray(items)) {\n      return value.map((item, index) => {\n        // Elements inside the tuple use their positional mapping; elements past it\n        // use the trailing single-`items` rest mapping (2020-12), if any.\n        const itemMapping = index < items.length ? items[index] : restItems;\n        return itemMapping ? restoreOriginalKeys(item, itemMapping, depth + 1) : item;\n      });\n    }\n    if (items) {\n      return value.map(item => restoreOriginalKeys(item, items, depth + 1));\n    }\n    return value;","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/utils/schemaPropertyKeys.ts#L375-L411","documentation":"The counterpart to sanitizeNode: when tool arguments (the actual call parameters) are restored to their original key names after execution, restoreOriginalKeys recurses with the same MAX_SCHEMA_DEPTH cap and throws when the arguments object nests deeper than allowed. This guards against runaway recursion on adversarial or cyclic inputs.","triggerScenarios":"Calling executeToolCall (or restoreOriginalKeys directly) with arguments whose object/array nesting depth exceeds MAX_SCHEMA_DEPTH — typically arguments crafted for a schema that itself hit error 410, or hand-built cyclic argument objects.","commonSituations":"Passing deeply/cyclically nested arguments from an LLM that hallucinated structure; arguments generated from a recursive type; a mismatch between a very deep schema and its serialized arguments.","solutions":["Validate/flatten arguments before invoking the tool so nesting stays within the SDK's cap","Fix the underlying schema (see error 410) — deep arguments usually accompany a deep schema","If arguments are machine-generated, add a depth check on the serialized JSON before sending"],"exampleFix":"// before\nawait composio.tools.execute(actionName, { args: deeplyNestedArgs });\n\n// after\nconst depth = (v: unknown, d = 0): number =>\n  v && typeof v === 'object'\n    ? Math.max(...Object.values(v as object).map(x => depth(x, d + 1)), d)\n    : d;\nif (depth(deeplyNestedArgs) > 10) throw new Error('Arguments too deeply nested');","handlingStrategy":"validation","validationCode":"const argDepth = (v: unknown, d = 0): number =>\n  v && typeof v === 'object'\n    ? Math.max(d, ...Object.values(v as object).map(x => argDepth(x, d + 1)))\n    : d;\nif (argDepth(args) >= 10) throw new Error('Arguments too deeply nested');","typeGuard":"null","tryCatchPattern":"try {\n  await composio.tools.execute(action, args);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Tool arguments nesting exceeded')) {\n    // flatten arguments and retry\n  }\n}","preventionTips":["Validate LLM-generated arguments with a depth-bounded schema before execution","Fix deep schemas at the source (see schema-side depth error)","Serialize and inspect arguments when tool calls fail unexpectedly"],"tags":["json-schema","tool-arguments","depth-limit","validation"],"backgroundTag":"schema-nesting-too-deep","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}