{"record":{"id":"9aab42062abd6ca6","repo":"cilium/cilium","slug":"error-formatting-summary-v-error-w","errorCode":null,"errorMessage":"error formatting summary: %v error: %w","messagePattern":"error formatting summary: (.+?) error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cilium-cli/connectivity/perf/common/metrics.go","lineNumber":192,"sourceCode":"\t\tif summary.Result.ThroughputMetric != nil {\n\t\t\tres := summary.Result.ThroughputMetric.toPerfData(labels, summary.PerfTest.Test+\"_\"+summary.PerfTest.Scenario)\n\t\t\tif _, ok := data[identifier+\"th\"]; !ok {\n\t\t\t\tdata[identifier+\"th\"] = res\n\t\t\t} else {\n\t\t\t\tmaps.Copy(data[identifier+\"th\"].Data, res.Data)\n\t\t\t}\n\t\t}\n\t}\n\treturn exportSummary(perfData{Version: \"v1\", DataItems: slices.Collect(maps.Values(data))}, reportDir)\n}\n\nfunc exportSummary(content perfData, reportDir string) error {\n\t// this filename needs to be in a specific format for perfdash\n\tfileName := strings.Join([]string{\"NetworkPerformance_benchmark\", time.Now().Format(time.RFC3339)}, \"_\")\n\tfilePath := path.Join(reportDir, strings.Join([]string{fileName, \"json\"}, \".\"))\n\tcontentStr, err := prettyPrintJSON(content)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error formatting summary: %v error: %w\", content, err)\n\t}\n\tif err := os.WriteFile(filePath, []byte(contentStr), 0600); err != nil {\n\t\treturn fmt.Errorf(\"writing to file %v error: %w\", filePath, err)\n\t}\n\treturn nil\n}\n\nfunc prettyPrintJSON(data any) (string, error) {\n\toutput := &bytes.Buffer{}\n\tif err := json.NewEncoder(output).Encode(data); err != nil {\n\t\treturn \"\", fmt.Errorf(\"building encoder error: %w\", err)\n\t}\n\tformatted := &bytes.Buffer{}\n\tif err := json.Indent(formatted, output.Bytes(), \"\", \"  \"); err != nil {\n\t\treturn \"\", fmt.Errorf(\"indenting error: %w\", err)\n\t}\n\treturn formatted.String(), nil\n}","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/cilium-cli/connectivity/perf/common/metrics.go#L174-L210","documentation":"In the perf connectivity tests, exportSummary serializes collected perfData to JSON (via prettyPrintJSON) and writes a perfdash-formatted file. If JSON marshaling of the summary fails, the error is wrapped with this message including the content being formatted. This means the performance results could not be serialized, so the benchmark report file is not produced.","triggerScenarios":"prettyPrintJSON returns an error for the given perfData — i.e. json.NewEncoder(...).Encode(data) fails while marshaling the summary structure (unsupported type such as a channel/func field, or a cyclic data structure).","commonSituations":"A perfData entry accidentally holds a non-serializable value (e.g. an error value stored in a map with a bad type, NaN/Inf in a custom MarshalJSON, or a custom MarshalJSON returning an error); regression after adding a field to perfData.","solutions":["Inspect the wrapped inner error and the printed content to find the field that fails to marshal","Check any custom MarshalJSON methods on perfData fields for returning errors (e.g. NaN/Inf values)","Fix the data at collection time so all perfData values are JSON-serializable","Validate with a quick json.Marshal(perfData{...}) unit test for new fields"],"exampleFix":"// before\ncontentStr, err := prettyPrintJSON(content)\nif err != nil {\n\treturn fmt.Errorf(\"error formatting summary: %v error: %w\", content, err)\n}\n// after\ncontentStr, err := prettyPrintJSON(sanitizePerfData(content)) // replace NaN/Inf with 0 before marshaling\nif err != nil {\n\treturn fmt.Errorf(\"error formatting summary: %v error: %w\", content, err)\n}","handlingStrategy":"validation","validationCode":"func validateSerializable(data perfData) error {\n\tb, err := json.Marshal(data)\n\tif err != nil { return err }\n\tif bytes.Contains(b, []byte(\"NaN\")) || bytes.Contains(b, []byte(\"Inf\")) {\n\t\treturn fmt.Errorf(\"non-JSON numbers in perf data\")\n\t}\n\treturn nil\n}\n// call validateSerializable(content) before exportSummary","typeGuard":"func isJSONSerializable(v any) bool {\n\t_, err := json.Marshal(v)\n\treturn err == nil\n}","tryCatchPattern":"if err := exportSummary(content, reportDir); err != nil {\n\tif strings.Contains(err.Error(), \"error formatting summary\") {\n\t\tlog.Printf(\"perf data not serializable, skipping perfdash export: %v\", err)\n\t\treturn nil // or fix the offending field\n\t}\n\treturn err\n}","preventionTips":["Keep perfData fields limited to JSON-safe types (string, float64, int)","Sanitize NaN/Inf metric values at collection time","Add a unit test marshaling representative perfData"],"tags":["json","serialization","performance-test","cilium"],"backgroundTag":"json-marshal-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}