siyuan-note/siyuan · error

value exceeds %d bytes

Error message

value exceeds %d bytes

What it means

Thrown by prepareValidationValue when the marshaled JSON of an input arguments map or an output structured-content value exceeds maxToolValueBytes (8 MiB, 8<<20). This is a hard ceiling protecting the validator from allocations and OOM when a client submits, or a tool returns, an enormous payload.

Source

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

		return fmt.Errorf("structured content is required when an output schema is defined")
	}
	value, err := prepareValidationValue(result.StructuredContent)
	if err != nil {
		return fmt.Errorf("prepare structured content: %w", err)
	}
	return validateResolved(ctx, validator.validationSlots, validator.output, value)
}

func prepareValidationValue(value any) (any, error) {
	if err := validateJSONComplexity(value, maxToolValueDepth, maxToolValueNodes); err != nil {
		return nil, err
	}
	data, err := json.Marshal(value)
	if err != nil {
		return nil, err
	}
	if len(data) > maxToolValueBytes {
		return nil, fmt.Errorf("value exceeds %d bytes", maxToolValueBytes)
	}
	var canonical any
	if err = json.Unmarshal(data, &canonical); err != nil {
		return nil, err
	}
	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()

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Reduce the payload: paginate large lists, store big binaries as file assets and pass a path/URL instead of inlining.
  2. Stream or chunk the operation rather than passing the full dataset through one tool invocation.
  3. If a higher limit is truly required, reconsider the design — 8 MiB is generous for structured JSON; a need to exceed it usually signals the wrong abstraction.
  4. Compress or deduplicate redundant repeated fields before marshaling.

Example fix

// before: inlining a large blob
arguments := map[string]any{"data": hugeBase64String}
// after: pass a reference, fetch content server-side
arguments := map[string]any{"assetPath": "/data/file.bin"}
Defensive patterns

Strategy: validation

Validate before calling

data, err := json.Marshal(value)
if err != nil { return err }
if len(data) > 8<<20 {
    return fmt.Errorf("value is %d bytes, max %d", len(data), 8<<20)
}

Prevention

When it happens

Trigger: ValidateInputContext with an arguments map whose JSON encoding is >8 MiB, or ValidateOutputContext with a StructuredContent whose JSON encoding is >8 MiB.

Common situations: A tool argument receives a huge base64 blob or an embedded file; a tool returns a full database dump as structured content; a client streams a giant array of records in one call instead of paginating.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/300bf8384fcbd405. Report an issue: GitHub.