{"record":{"id":"f35dcd9e242a4f43","repo":"siyuan-note/siyuan","slug":"json-depth-exceeds-d","errorCode":null,"errorMessage":"JSON depth exceeds %d","messagePattern":"JSON depth exceeds (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/tools/validation.go","lineNumber":195,"sourceCode":"\t\tresult <- err\n\t}()\n\n\tselect {\n\tcase err := <-result:\n\t\treturn err\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-timer.C:\n\t\treturn fmt.Errorf(\"validation exceeded %s\", toolValidationTime)\n\t}\n}\n\nfunc validateJSONComplexity(value any, maxDepth, maxNodes int) error {\n\tnodes := 0\n\tvar walk func(any, int) error\n\twalk = func(current any, depth int) error {\n\t\tif depth > maxDepth {\n\t\t\treturn fmt.Errorf(\"JSON depth exceeds %d\", maxDepth)\n\t\t}\n\t\tnodes++\n\t\tif nodes > maxNodes {\n\t\t\treturn fmt.Errorf(\"JSON node count exceeds %d\", maxNodes)\n\t\t}\n\t\tswitch typed := current.(type) {\n\t\tcase map[string]any:\n\t\t\tfor _, child := range typed {\n\t\t\t\tif err := walk(child, depth+1); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\tcase []any:\n\t\t\tfor _, child := range typed {\n\t\t\t\tif err := walk(child, depth+1); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/tools/validation.go#L177-L213","documentation":"Thrown by validateJSONComplexity (via the recursive walk) when the depth of a JSON value exceeds the supplied maxDepth. For tool schemas the limit is maxToolSchemaDepth=64; for input/output values it is maxToolValueDepth=128. Depth is incremented for each nested object property or array element, so this guards against stack overflow and exponential traversal.","triggerScenarios":"Submitting a schema or a value whose nesting depth exceeds 64 (schema) or 128 (value). validateJSONComplexity is called in resolveToolSchema (schemas) and in prepareValidationValue (values).","commonSituations":"A recursively defined data structure serialized to arbitrary depth; a tool argument that accepts a deeply nested tree (e.g., a parsed AST or a thread of replies) without a depth cap; a generated schema that nests $defs deeply.","solutions":["Flatten deeply nested data before submission (e.g., represent a tree as a flat list of {id,parentId} records).","Cap nesting depth at the source: enforce a maximum depth when constructing the value.","If the data is legitimately deep but within reason, confirm it stays under 64 (schema) or 128 (value) and that you are not accidentally double-nesting (wrapping in an extra array/object layer)."],"exampleFix":"// before: arbitrarily deep nested tree\ndeep := buildTree(200) // depth 200 > 128\n// after: flatten\nflat := flatten(deep) // []map[string]any{\"id\":..,\"parentID\":..}","handlingStrategy":"validation","validationCode":"func depth(v any, d int) int {\n    max := d\n    switch t := v.(type) {\n    case map[string]any:\n        for _, c := range t { if m := depth(c, d+1); m > max { max = m } }\n    case []any:\n        for _, c := range t { if m := depth(c, d+1); m > max { max = m } }\n    }\n    return max\n}\nif depth(value, 0) > 128 { return errors.New(\"value too deep\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Flatten tree-shaped data to {id,parentId} lists before submission.","Enforce a maximum nesting depth at the data source.","Reject or paginate inputs that exceed a sane depth before calling the validator."],"tags":["mcp","validation","json","depth-limit"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}