siyuan-note/siyuan · error
JSON depth exceeds
Error message
JSON depth exceeds %d
What it means
validateJSONComplexity walks an unmarshaled JSON value and rejects it when nesting depth exceeds maxDepth. This guards the kernel's MCP tool layer against deeply nested inputs that could blow the stack or consume excessive memory during schema validation. The depth of the JSON tree is compared per node as the walker recurses.
Solutions
- Flatten the JSON payload so nesting stays within the allowed depth limit
- Reduce redundant wrapper layers (e.g. objects with a single child key)
- If the limit is genuinely too low for a legitimate use case, raise maxDepth at the call site of validateJSONComplexity
- Check the serialized payload with a JSON depth counter before sending
Example fix
// before
const payload = {a:{b:{c:{d:{e:{f:{g:{h:1}}}}}}}} // too deep
// after
const payload = {a_b_c_d_e_f_g_h: 1} // flattened Defensive patterns
Strategy: validation
Validate before calling
function jsonDepth(v, d = 0) { if (d > 32) return d; if (Array.isArray(v)) return Math.max(0, ...v.map(x => jsonDepth(x, d + 1))); if (v && typeof v === 'object') return Math.max(0, ...Object.values(v).map(x => jsonDepth(x, d + 1))); return d; }
if (jsonDepth(payload) > 32) throw new Error('payload nesting too deep'); Type guard
const isShallowEnough = (v, max = 32) => jsonDepth(v) <= max;
Try / catch
null
Prevention
- Avoid recursive wrapper structures when building tool arguments
- Count depth before serializing large config objects
- Keep tool input schemas flat; pass references (IDs) instead of nested data
When it happens
Trigger: Any MCP tool call whose JSON argument (tool input schema or parameters) nests maps/arrays/slices deeper than the configured maxDepth when passed to validateJSONComplexity.
Common situations: Programmatic clients serializing deeply nested config objects, recursive data structures that accidentally self-reference in JSON generation, or payloads built by wrapping many layers of wrappers/arrays.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- JSON node count exceeds
- invalid tool arguments
- attr must be a string or null (got %T)
- attribute view custom colors count exceeds the
- builtin color must not be null
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/f35dcd9e242a4f43.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/mcp/tools/validation.go:194
<-validationSlots
result <- err
}()
select {
case err := <-result:
return err
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
return fmt.Errorf("validation exceeded %s", toolValidationTime)
}
}
func validateJSONComplexity(value any, maxDepth, maxNodes int) error {
nodes := 0
var walk func(any, int) error
walk = func(current any, depth int) error {
if depth > maxDepth {
return fmt.Errorf("JSON depth exceeds %d", maxDepth)
}
nodes++
if nodes > maxNodes {
return fmt.Errorf("JSON node count exceeds %d", maxNodes)
}
switch typed := current.(type) {
case map[string]any:
for _, child := range typed {
if err := walk(child, depth+1); err != nil {
return err
}
}
case []any:
for _, child := range typed {
if err := walk(child, depth+1); err != nil {
return err
}View on GitHub (pinned to 9f775e8a12)