siyuan-note/siyuan · error
structured content is required when an output schema is defi
Error message
structured content is required when an output schema is defined
What it means
Thrown by ValidateOutputContext when a tool has a compiled output schema (validator.output != nil), the result is not an error result (result.IsError is false), but result.HasStructuredContent() returns false. The MCP contract requires that successful results of tools with an output schema carry structured content that conforms to that schema so consumers can rely on it.
Source
Thrown at kernel/mcp/tools/validation.go:128
return nil
}
value, err := prepareValidationValue(arguments)
if err != nil {
return err
}
return validateResolved(ctx, validator.validationSlots, validator.input, value)
}
func (validator *ToolValidator) ValidateOutput(result CallToolResult) error {
return validator.ValidateOutputContext(context.Background(), result)
}
func (validator *ToolValidator) ValidateOutputContext(ctx context.Context, result CallToolResult) error {
if validator == nil || validator.output == nil || result.IsError {
return nil
}
if !result.HasStructuredContent() {
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)View on GitHub (pinned to 251596fc0d)
Solutions
- Populate result.StructuredContent with a value matching the declared OutputSchema on every success path.
- If the tool only ever returns unstructured text, remove the OutputSchema (set tool.OutputSchema to nil).
- When the operation genuinely fails, set result.IsError = true — error results are exempt from the structured-content requirement.
Example fix
// before
return CallToolResult{Content: []Content{{Type: "text", Text: "ok"}}
// after — tool has OutputSchema {type:object, properties:{ok:{type:boolean}}}
return CallToolResult{
Content: []Content{{Type: "text", Text: "ok"}},
StructuredContent: map[string]any{"ok": true},
} Defensive patterns
Strategy: validation
Validate before calling
if tool.OutputSchema != nil && !result.IsError && !result.HasStructuredContent() {
result.StructuredContent = map[string]any{} // or populate per schema
} Type guard
func hasRequiredOutput(result CallToolResult, hasOutputSchema bool) bool {
return !hasOutputSchema || result.IsError || result.HasStructuredContent()
} Prevention
- Every success path of a tool with an OutputSchema must set StructuredContent.
- If a handler only returns text, do not declare an OutputSchema for that tool.
- Use error results (IsError=true) for failure paths to skip the structured-content requirement intentionally.
When it happens
Trigger: Calling a tool that defines OutputSchema, the handler returns a CallToolResult with only text content (or no content) and IsError=false, so HasStructuredContent() is false.
Common situations: A tool handler returns text-only output but the tool declared an output schema; a handler sets StructuredContent to nil on success paths; refactoring that adds an OutputSchema without updating the handler to populate StructuredContent.
Related errors
- prepare structured content: %w
- tools/list returned an empty response
- tools/list repeated cursor %q
- unsupported server type: %s
- command is required for stdio server
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/51b1bdabc89100c6.
Report an issue: GitHub.