{"record":{"id":"8272f72c23639392","repo":"flipped-aurora/gin-vue-admin","slug":"w-8272f7","errorCode":null,"errorMessage":"序列化结果失败: %w","messagePattern":"序列化结果失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/result.go","lineNumber":13,"sourceCode":"package mcpTool\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/mark3labs/mcp-go/mcp\"\n)\n\nfunc textResultWithJSON(title string, payload any) (*mcp.CallToolResult, error) {\n\tresultJSON, err := json.MarshalIndent(payload, \"\", \"  \")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"序列化结果失败: %w\", err)\n\t}\n\n\ttext := string(resultJSON)\n\tif title != \"\" {\n\t\ttext = fmt.Sprintf(\"%s\\n\\n%s\", title, text)\n\t}\n\n\treturn &mcp.CallToolResult{\n\t\tContent: []mcp.Content{\n\t\t\tmcp.TextContent{\n\t\t\t\tType: \"text\",\n\t\t\t\tText: text,\n\t\t\t},\n\t\t},\n\t}, nil\n}\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/result.go#L1-L30","documentation":"json.MarshalIndent failure inside textResultWithJSON, the shared helper that turns a tool payload into an MCP CallToolResult text. Marshal of plain Go data from these tools practically only fails with unsupported types (channels, funcs, cyclic pointers, NaN/Inf floats).","triggerScenarios":"Any Handle that builds its result payload with a value json cannot encode (e.g. a channel/func field, a cyclic reference, or math NaN/Inf in a float field) and then calls textResultWithJSON.","commonSituations":"Custom structs added to result types with non-serializable fields and no json tag handling; accidentally passing a raw func or nil-typed interface holding an unsupported value; injecting NaN from a division by zero.","solutions":["Find the offending field by marshaling the payload in isolation to reproduce the error","Remove or replace non-serializable fields (channels, funcs, cycles) in result structs","Add json tags and custom MarshalJSON for special types","Sanitize float values (NaN/Inf) to 0 or null before building the payload"],"exampleFix":"// before\nresult := orgAssignChange{Before: currentDeptIDs, After: merged, Added: added, Callback: logFn} // func field\n// after\nresult := orgAssignChange{Before: currentDeptIDs, After: merged, Added: added} // drop non-serializable field","handlingStrategy":"type-guard","validationCode":"if err := json.Marshal(payload); err != nil {\n    return fmt.Errorf(\"payload not serializable: %w\", err)\n}","typeGuard":"func jsonSafe(v any) bool {\n    switch v.(type) {\n    case chan struct{}, func(), unsafe.Pointer:\n        return false\n    }\n    return !reflect.ValueOf(v).IsValid() || !hasCycle(reflect.ValueOf(v))\n}","tryCatchPattern":"result, err := tool.Handle(ctx, args)\nif err != nil {\n    if strings.Contains(err.Error(), \"序列化结果失败\") || errors.Is(err, json.UnsupportedTypeError{}) || errors.Is(err, json.UnsupportedValueError{}) {\n        // log the payload type; fix the result struct field causing it\n    }\n    return err\n}","preventionTips":["Keep result structs free of chan/func/cyclic fields","Add json tags to every result struct field","Test Handle output serialization in unit tests, not only in production"],"tags":["json","serialization","mcp"],"backgroundTag":"json-marshal-unsupported-type","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}