{"record":{"id":"1979e25f70b41b5c","repo":"siyuan-note/siyuan","slug":"prepare-structured-content-w","errorCode":null,"errorMessage":"prepare structured content: %w","messagePattern":"prepare structured content: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/tools/validation.go","lineNumber":132,"sourceCode":"\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)\n\t}\n\tvar canonical any\n\tif err = json.Unmarshal(data, &canonical); err != nil {\n\t\treturn nil, err","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/tools/validation.go#L114-L150","documentation":"Wraps any error returned by prepareValidationValue while preparing the structured content of a tool result for output-schema validation. The underlying cause is almost always a JSON-complexity limit (depth/nodes/bytes exceeded, see errors 364/367/368) or a json.Marshal/Unmarshal failure on the StructuredContent value. The %w verb preserves the wrapped error for inspection with errors.Is/errors.As.","triggerScenarios":"ValidateOutputContext calls prepareValidationValue(result.StructuredContent); that value fails validateJSONComplexity, exceeds maxToolValueBytes (8 MiB), or contains a type that json.Marshal cannot encode (e.g., a channel, func, or cyclic struct).","commonSituations":"A tool returns a deeply nested or very large structured object; a handler stores a non-JSON-serializable Go value (chan, func, unsafe.Pointer, or a struct with unexported fields and no marshaler) into StructuredContent; a handler accidentally embeds the entire request or a live pointer graph.","solutions":["Inspect the wrapped error with errors.Unwrap/errors.As to identify whether it is a size, depth, node-count, or marshal error, then address that specific limit.","Ensure StructuredContent is a plain JSON-serializable value (map[string]any, slices of primitives, structs with JSON tags).","Trim or paginate large outputs so the marshaled size stays under 8 MiB and depth under 128.","Unit-test the handler's StructuredContent by marshaling it through encoding/json before wiring it to the tool."],"exampleFix":"// before: handler stores a non-serializable value\nresult.StructuredContent = someLiveObjectWithChannels\n// after\nresult.StructuredContent = map[string]any{\"id\": obj.ID, \"name\": obj.Name}","handlingStrategy":"try-catch","validationCode":"if _, err := json.Marshal(structuredContent); err != nil { return fmt.Errorf(\"structured content not serializable: %w\", err) }","typeGuard":null,"tryCatchPattern":"err := validator.ValidateOutputContext(ctx, result)\nif err != nil {\n    if inner := errors.Unwrap(err); inner != nil { /* inspect complexity/marshal cause */ }\n    // degrade: return text content only, or convert to IsError result\n}","preventionTips":["Only store JSON-serializable values (maps, slices, primitives, tagged structs) in StructuredContent.","Unit-test marshaling each handler's structured output before wiring it to a tool.","Keep structured outputs within the depth/node/byte budgets (128 / 262144 / 8 MiB)."],"tags":["mcp","output-schema","validation","serialization"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}