{"record":{"id":"c54f1fe55d6300b9","repo":"siyuan-note/siyuan","slug":"json-node-count-exceeds-d","errorCode":null,"errorMessage":"JSON node count exceeds %d","messagePattern":"JSON node count exceeds (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/tools/validation.go","lineNumber":199,"sourceCode":"\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}\n\t\t}\n\t\treturn nil\n\t}\n\treturn walk(value, 0)","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/tools/validation.go#L181-L217","documentation":"Thrown by validateJSONComplexity when the total node count (every map, array element, and scalar visited by the recursive walk) exceeds maxNodes. For schemas the limit is maxToolSchemaNodes=16384 (16<<10); for values it is maxToolValueNodes=262144 (256<<10). This bounds the work the validator must perform.","triggerScenarios":"Submitting a schema or value with more than 16384 (schema) or 262144 (value) JSON nodes. Each object/array/scalar counts as one node.","commonSituations":"A schema with thousands of properties or a huge enum; a value that is a very long array of records (e.g., 300k entries each counting as a node); auto-generated schemas from large data models.","solutions":["Paginate or chunk large arrays so each call stays under the node budget.","Prune unused properties from auto-generated schemas; split a monolithic schema into per-resource schemas.","If returning a large collection, return a summary plus a cursor/offset and a separate fetch tool."],"exampleFix":"// before: return 300000 records as one structured value\nresult.StructuredContent = allRecords\n// after: paginate\nresult.StructuredContent = map[string]any{\"items\": page, \"nextCursor\": cursor}","handlingStrategy":"validation","validationCode":"func countNodes(v any) int {\n    n := 1\n    switch t := v.(type) {\n    case map[string]any: for _, c := range t { n += countNodes(c) }\n    case []any: for _, c := range t { n += countNodes(c) }\n    }\n    return n\n}\nif countNodes(value) > 256<<10 { return errors.New(\"too many nodes\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Paginate long arrays before sending them as a single value.","Prune unused properties from auto-generated schemas.","Return summaries plus cursors for large collections instead of full dumps."],"tags":["mcp","validation","json","node-limit","pagination"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}