{"record":{"id":"5c4963488186970d","repo":"ComposioHQ/composio","slug":"tool-arguments-exceed-maximum-nesting-depth-of-ma","errorCode":null,"errorMessage":"Tool arguments exceed maximum nesting depth of {MAX_NODE_DEPTH}","messagePattern":"Tool arguments exceed maximum nesting depth of (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/composio/utils/strict_schema.py","lineNumber":436,"sourceCode":"            return candidate\n        for keyword in (\"anyOf\", \"oneOf\"):\n            branches = candidate.get(keyword)\n            if not isinstance(branches, list):\n                continue\n            for branch in branches:\n                found = find(branch, depth + 1)\n                if found is not None:\n                    return found\n        return None\n\n    return find(resolved, 0) or resolved\n\n\ndef _omit_nulls(\n    value: t.Any, schema: t.Any, root: dict[str, t.Any], depth: int\n) -> t.Any:\n    if depth > MAX_NODE_DEPTH:\n        raise ValueError(\n            f\"Tool arguments exceed maximum nesting depth of {MAX_NODE_DEPTH}\"\n        )\n    node = _select_branch_for(schema, value, root) or {}\n    if isinstance(value, list):\n        items = node.get(\"items\") if isinstance(node.get(\"items\"), dict) else None\n        return [_omit_nulls(item, items, root, depth + 1) for item in value]\n    if not isinstance(value, dict):\n        return value\n    declared = node.get(\"properties\")\n    properties: dict[str, t.Any] = declared if isinstance(declared, dict) else {}\n    clone: dict[str, t.Any] = {}\n    for key, child in value.items():\n        property_schema = properties.get(key)\n        if child is None:\n            if property_schema is None or _schema_accepts_null(property_schema, root):\n                clone[key] = child\n            continue\n        clone[key] = _omit_nulls(child, property_schema, root, depth + 1)","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/python/composio/utils/strict_schema.py#L418-L454","documentation":"omit_null_tool_arguments walks the argument payload against the schema to drop null-valued optional fields, and _omit_nulls enforces MAX_NODE_DEPTH on the combined value/schema recursion. Deeply nested arguments (or a schema that makes the walker chase many branches) exceed the cap and raise ValueError.","triggerScenarios":"Calling a tool (or explicitly omit_null_tool_arguments) with arguments nested deeper than the limit — e.g. deeply nested JSON payloads from file parsing, or list-of-list structures combined with anyOf-heavy schemas that multiply traversal depth.","commonSituations":"Uploading parsed JSON documents (ASTs, configs, serialized trees) as tool arguments; LLMs generating extremely nested output; payloads that grew from data-driven nesting without a flattening step.","solutions":["Flatten arguments before the call: send big/deep blobs as a single string field or file reference rather than structured arguments","Pre-check depth with a quick recursive counter and split/truncate the payload","Simplify the tool's input schema so anyOf/branch selection doesn't compound depth","If the payload is legitimately huge, use file upload paths instead of inline arguments"],"exampleFix":"# before\nargs = json.loads(deep_document_text)  # possibly 50+ levels\ntool.run(args)\n# after\nargs = {\"document\": deep_document_text}\ntool.run(args)","handlingStrategy":"validation","validationCode":"def payload_depth(v, d=0):\n    if isinstance(v, dict): return max([payload_depth(x, d+1) for x in v.values()], default=d)\n    if isinstance(v, list): return max([payload_depth(x, d+1) for x in v], default=d)\n    return d\nif payload_depth(args) > 50: args = {\"blob\": json.dumps(args)}","typeGuard":null,"tryCatchPattern":"try:\n    tool.run(args)\nexcept ValueError as e:\n    if \"nesting depth\" in str(e):\n        tool.run({\"document\": json.dumps(args)})","preventionTips":["Send large/deep payloads as strings or file references, not structured args","Flatten argument structures in your own layer","Cap LLM output nesting via prompt constraints"],"tags":["tool-arguments","nesting-depth","null-omission"],"backgroundTag":"arguments-nesting-depth-exceeded","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}