{"record":{"id":"4a38fa6003b312a9","repo":"ComposioHQ/composio","slug":"tool-arguments-exceed-maximum-nesting-depth-of-m","errorCode":null,"errorMessage":"Tool arguments exceed maximum nesting depth of ${MAX_NODE_DEPTH}","messagePattern":"Tool arguments exceed maximum nesting depth of (.+?)","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ts/packages/core/src/utils/jsonSchema.ts","lineNumber":952,"sourceCode":"      if (!Array.isArray(branches)) continue;\n      for (const branch of branches) {\n        const found = find(branch, depth + 1);\n        if (found) return found;\n      }\n    }\n    return undefined;\n  };\n  return find(resolved, 0) ?? resolved;\n}\n\nfunction omitNulls(\n  value: unknown,\n  schema: unknown,\n  root: Record<string, unknown>,\n  depth: number\n): unknown {\n  if (depth > MAX_NODE_DEPTH) {\n    throw new RangeError(`Tool arguments exceed maximum nesting depth of ${MAX_NODE_DEPTH}`);\n  }\n  const node = selectBranchFor(schema, value, root);\n  if (Array.isArray(value)) {\n    const items = node && isPlainObject(node.items) ? node.items : undefined;\n    return value.map(item => omitNulls(item, items, root, depth + 1));\n  }\n  if (!isPlainObject(value)) return value;\n\n  const properties = node && isPlainObject(node.properties) ? node.properties : {};\n  const clone: Record<string, unknown> = {};\n  for (const [key, child] of Object.entries(value)) {\n    const propertySchema = Object.prototype.hasOwnProperty.call(properties, key)\n      ? properties[key]\n      : undefined;\n    if (child === null) {\n      if (propertySchema === undefined || schemaAcceptsNull(propertySchema, root)) {\n        setOwn(clone, key, child);\n      }","sourceCodeStart":934,"sourceCodeEnd":970,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/utils/jsonSchema.ts#L934-L970","documentation":"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.","triggerScenarios":"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.","commonSituations":"Untrusted or model-generated tool arguments; clients that build arguments recursively; crafted payloads.","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."],"exampleFix":"// before\nawait tool.execute(args);\n// after\nconst depth = (v: unknown, d = 0): number =>\n  v && typeof v === 'object'\n    ? Math.max(d, ...Object.values(v as object).map(x => depth(x, d + 1)))\n    : d;\nif (depth(args) > 100) throw new Error('arguments too deeply nested');\nawait tool.execute(args);","handlingStrategy":"validation","validationCode":"const depth = (v: unknown, d = 0): number =>\n  v && typeof v === 'object'\n    ? Math.max(d, ...Object.values(v as object).map(x => depth(x, d + 1)))\n    : d;\nif (depth(args) > 100) throw new Error('arguments too deep');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["JSON.stringify arguments first to surface cycles.","Cap nesting of model-generated arguments."],"tags":["tool-arguments","depth-limit","json-schema","typescript"],"backgroundTag":"payload-too-deeply-nested","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}