siyuan-note/siyuan · error

invalid output schema: %w

Error message

invalid output schema: %w

What it means

When a Tool declares an OutputSchema, CompileToolValidator resolves it like the input schema and wraps failures with "invalid output schema: %w". The same rules apply: valid JSON Schema, within the 1 MiB / depth / node limits. This error means the tool's declared output schema cannot be compiled into a validator.

Source

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

	input           *jsonschema.Resolved
	output          *jsonschema.Resolved
	validationSlots chan struct{}
}

func CompileToolValidator(tool *Tool) (*ToolValidator, error) {
	if tool == nil {
		return nil, fmt.Errorf("tool is nil")
	}

	input, err := resolveToolSchema(tool.InputSchema, true)
	if err != nil {
		return nil, fmt.Errorf("invalid input schema: %w", err)
	}

	var output *jsonschema.Resolved
	if tool.OutputSchema != nil {
		if output, err = resolveToolSchema(*tool.OutputSchema, false); err != nil {
			return nil, fmt.Errorf("invalid output schema: %w", err)
		}
	}
	return &ToolValidator{
		input:           input,
		output:          output,
		validationSlots: make(chan struct{}, toolValidationConcurrency),
	}, nil
}

func resolveToolSchema(schema ToolSchema, requireObject bool) (*jsonschema.Resolved, error) {
	if schema.Raw != nil {
		if err := validateJSONComplexity(schema.Raw, maxToolSchemaDepth, maxToolSchemaNodes); err != nil {
			return nil, err
		}
	}
	data, err := json.Marshal(schema)
	if err != nil {
		return nil, err

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Inspect the wrapped cause for the exact failure.
  2. Fix invalid keywords/types in the output schema.
  3. Simplify or split the schema to fit size/depth/node limits.
  4. Set OutputSchema to nil if structured output is not actually needed.

Example fix

// before
OutputSchema: &map[string]any{"type": "objet"}
// after
OutputSchema: &map[string]any{"type": "object", "properties": map[string]any{...}}
Defensive patterns

Strategy: validation

Validate before calling

if out != nil {
    data, _ := json.Marshal(*out)
    if len(data) > 1<<20 {
        return errors.New("output schema exceeds 1MiB")
    }
}

Type guard

func hasOutputSchema(t *tools.Tool) bool { return t != nil && t.OutputSchema != nil }

Try / catch

err := tools.SetTool(name, def)
if err != nil && strings.Contains(err.Error(), "invalid output schema") {
    log.Printf("tool %s: fix OutputSchema: %v", name, err)
    def.OutputSchema = nil // degrade gracefully, retry
    err = tools.SetTool(name, def)
}

Prevention

When it happens

Trigger: Setting Tool.OutputSchema to a malformed schema, an oversized (>1 MiB) schema, an over-complex schema, or one that fails jsonschema parsing during SetTool/buildCapabilitySet.

Common situations: Adding structured tool output support with a hand-crafted output schema containing invalid keywords; auto-generated response schemas exceeding limits; typo'd type names in the output schema.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/a6406e3797e95c6a. Report an issue: GitHub.