{"record":{"id":"343d1745488164f9","repo":"siyuan-note/siyuan","slug":"validation-exceeded-s","errorCode":null,"errorMessage":"validation exceeded %s","messagePattern":"validation exceeded (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/mcp/tools/validation.go","lineNumber":186,"sourceCode":"\t\treturn ctx.Err()\n\tcase <-timer.C:\n\t\treturn fmt.Errorf(\"validation did not start within %s\", toolValidationTime)\n\t}\n\n\tresult := make(chan error, 1)\n\tgo func() {\n\t\terr := schema.Validate(value)\n\t\t<-validationSlots\n\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 {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/mcp/tools/validation.go#L168-L204","documentation":"Once a validation slot is acquired, validateResolved runs jsonschema.Validate in a goroutine and waits up to toolValidationTime (2 seconds) for it to finish. If validation does not complete within 2 seconds — pathological payloads near the size/complexity limits on a slow host — the wait is abandoned with this timeout and the validation result is discarded.","triggerScenarios":"Validating an input or structured-output value whose complexity (up to 128 depth / 262144 nodes) makes jsonschema.Validate exceed 2 seconds; heavily loaded CPU; an adversarial payload crafted to stress the validator (billion-laughs-style nesting within limits).","commonSituations":"Stress tests with maximal-size payloads; production hosts under CPU starvation validating many large tool payloads; regex-heavy schema keywords evaluated against long strings.","solutions":["Retry with a smaller, simpler payload; split large arguments into multiple calls.","Reduce nesting and node count of the value being validated.","Simplify the tool's schema (fewer patternProperties/regex constraints) so validation is cheaper.","Raise toolValidationTime in validation.go only if legitimate payloads genuinely need longer."],"exampleFix":"// before\nvalidateResolved(ctx, slots, schema, deeplyNested8MBValue) // Validate > 2s\n// after\nvalidateResolved(ctx, slots, schema, summarizedValue) // flattened, paginated value validates well under 2s","handlingStrategy":"retry","validationCode":"const depth = v => typeof v === \"object\" && v !== null ? 1 + Math.max(0, ...Object.values(v).map(depth)) : 0;\nif (depth(payload) > 100) throw new Error(\"payload too deeply nested for fast validation\");","typeGuard":null,"tryCatchPattern":"if err := validator.ValidateOutput(result); err != nil {\n  if strings.Contains(err.Error(), \"validation exceeded\") {\n    // simplify payload or retry with a smaller value\n    return retryWithTruncatedPayload(result)\n  }\n  return err\n}","preventionTips":["Keep validated values small and shallow — near-limit payloads (8 MiB / 262144 nodes) risk the 2s budget.","Avoid regex-heavy schema keywords over long strings in tool schemas.","Reduce host CPU contention; validation runs on a shared 4-slot pool.","Tune toolValidationTime only after profiling legitimate worst-case payloads."],"tags":["timeout","performance","mcp","validation"],"backgroundTag":"request-timeout","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}