siyuan-note/siyuan · warning

validation did not start within

Error message

validation did not start within %s

What it means

validateResolved gates schema validation behind a semaphore of toolValidationConcurrency=4 slots and a 2-second (toolValidationTime) acquisition deadline. If no slot frees up within 2 seconds — because four other validations are concurrently holding slots on slow, pathological payloads — the validation is abandoned with this timeout rather than queued indefinitely.

Solutions

  1. Retry the tool call; the condition is usually transient under load.
  2. Reduce concurrent tool invocations from the client (serialize or batch fewer calls).
  3. Shrink argument/output payload sizes so each validation completes faster and slots free quickly.
  4. Increase toolValidationConcurrency or toolValidationTime in validation.go if sustained parallelism is a legitimate workload.

Example fix

// before
// client fires 32 tool calls in parallel; 5th+ wait > 2s
await Promise.all(ids.map(callTool))
// after
// limit in-flight calls to below the 4-slot validation concurrency
await pLimit(4, ids.map(callTool))
Defensive patterns

Strategy: retry

Try / catch

err := validator.ValidateInputContext(ctx, args)
if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), "validation did not start within") {
  // transient slot starvation: back off and retry once
  time.Sleep(250 * time.Millisecond)
  err = validator.ValidateInputContext(ctx, args)
}

Prevention

When it happens

Trigger: More than 4 concurrent tool calls whose input/output validation is in progress, each taking long enough (large payloads near the 8 MiB / 262144-node limits) that a fifth waits over 2 seconds for a slot; typically under heavy parallel MCP traffic.

Common situations: Load/stress tests firing many simultaneous tool calls; a slow or adversarial payload monopolizing validation slots; saturated CPU on the host slowing jsonschema.Validate for all in-flight calls.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

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

	if err = validateJSONComplexity(canonical, maxToolValueDepth, maxToolValueNodes); err != nil {
		return nil, err
	}
	return canonical, nil
}

func validateResolved(ctx context.Context, validationSlots chan struct{}, schema *jsonschema.Resolved, value any) error {
	if ctx == nil {
		ctx = context.Background()
	}
	timer := time.NewTimer(toolValidationTime)
	defer timer.Stop()

	select {
	case validationSlots <- struct{}{}:
	case <-ctx.Done():
		return ctx.Err()
	case <-timer.C:
		return fmt.Errorf("validation did not start within %s", toolValidationTime)
	}

	result := make(chan error, 1)
	go func() {
		err := schema.Validate(value)
		<-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)
	}
}

View on GitHub (pinned to 9f775e8a12)