{"record":{"id":"51b1bdabc89100c6","repo":"siyuan-note/siyuan","slug":"structured-content-is-required-when-an-output-sche","errorCode":null,"errorMessage":"structured content is required when an output schema is defined","messagePattern":"structured content is required when an output schema is defined","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/tools/validation.go","lineNumber":128,"sourceCode":"\t\treturn nil\n\t}\n\tvalue, err := prepareValidationValue(arguments)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn validateResolved(ctx, validator.validationSlots, validator.input, value)\n}\n\nfunc (validator *ToolValidator) ValidateOutput(result CallToolResult) error {\n\treturn validator.ValidateOutputContext(context.Background(), result)\n}\n\nfunc (validator *ToolValidator) ValidateOutputContext(ctx context.Context, result CallToolResult) error {\n\tif validator == nil || validator.output == nil || result.IsError {\n\t\treturn nil\n\t}\n\tif !result.HasStructuredContent() {\n\t\treturn fmt.Errorf(\"structured content is required when an output schema is defined\")\n\t}\n\tvalue, err := prepareValidationValue(result.StructuredContent)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"prepare structured content: %w\", err)\n\t}\n\treturn validateResolved(ctx, validator.validationSlots, validator.output, value)\n}\n\nfunc prepareValidationValue(value any) (any, error) {\n\tif err := validateJSONComplexity(value, maxToolValueDepth, maxToolValueNodes); err != nil {\n\t\treturn nil, err\n\t}\n\tdata, err := json.Marshal(value)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(data) > maxToolValueBytes {\n\t\treturn nil, fmt.Errorf(\"value exceeds %d bytes\", maxToolValueBytes)","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/tools/validation.go#L110-L146","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nreturn CallToolResult{Content: []Content{{Type: \"text\", Text: \"ok\"}}\n// after — tool has OutputSchema {type:object, properties:{ok:{type:boolean}}}\nreturn CallToolResult{\n  Content: []Content{{Type: \"text\", Text: \"ok\"}},\n  StructuredContent: map[string]any{\"ok\": true},\n}","handlingStrategy":"validation","validationCode":"if tool.OutputSchema != nil && !result.IsError && !result.HasStructuredContent() {\n    result.StructuredContent = map[string]any{} // or populate per schema\n}","typeGuard":"func hasRequiredOutput(result CallToolResult, hasOutputSchema bool) bool {\n    return !hasOutputSchema || result.IsError || result.HasStructuredContent()\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["mcp","output-schema","validation","structured-content"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}