siyuan-note/siyuan · error

JSON node count exceeds

Error message

JSON node count exceeds %d

What it means

validateJSONComplexity counts every node visited while walking the JSON value and fails once the total exceeds maxNodes. This protects the MCP tool layer from very large argument payloads that would be expensive to validate, index, or persist. The counter is global across the whole tree, not per branch.

Solutions

  1. Reduce the payload size — split it into multiple smaller tool calls or paginate
  2. Compress data structure: move bulk data out of JSON arguments (e.g. reference a file/block ID instead)
  3. Raise maxNodes at the call site if legitimate large payloads must be accepted
  4. Count JSON nodes client-side before sending and truncate

Example fix

// before
await callTool("import", {items: hugeArray}) // node count exceeded
// after
for (const chunk of _.chunk(hugeArray, 100)) await callTool("import", {items: chunk})
Defensive patterns

Strategy: validation

Validate before calling

function countNodes(v) { if (Array.isArray(v)) return 1 + v.reduce((s, x) => s + countNodes(x), 0); if (v && typeof v === 'object') return 1 + Object.values(v).reduce((s, x) => s + countNodes(x), 0); return 1; }
if (countNodes(payload) > 100000) throw new Error('payload too large; split into batches');

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: An MCP tool call whose JSON argument contains more total nodes (keys, array elements, scalars) than maxNodes when passed to validateJSONComplexity.

Common situations: Bulk-import payloads with huge arrays, generated JSON from dumping an entire dataset into a tool argument, or loops that append entries without size checks.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/c54f1fe55d6300b9. Report an issue: GitHub.

Appendix: source

Thrown at kernel/mcp/tools/validation.go:198

	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
				}
			}
		}
		return nil
	}

View on GitHub (pinned to 9f775e8a12)