{"record":{"id":"77277d2f9f8c8bcc","repo":"golang/go","slug":"preprocessed-profile-contains-duplicate-edge-v","errorCode":null,"errorMessage":"preprocessed profile contains duplicate edge %+v","messagePattern":"preprocessed profile contains duplicate edge %\\+v","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/pgo/deserialize.go","lineNumber":92,"sourceCode":"\n\t\tco, err := strconv.Atoi(split[0])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"preprocessed profile error processing call line: %w\", err)\n\t\t}\n\n\t\tedge := NamedCallEdge{\n\t\t\tCallerName:     callerName,\n\t\t\tCalleeName:     calleeName,\n\t\t\tCallSiteOffset: co,\n\t\t}\n\n\t\tweight, err := strconv.ParseInt(split[1], 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"preprocessed profile error processing call weight: %w\", err)\n\t\t}\n\n\t\tif _, ok := d.NamedEdgeMap.Weight[edge]; ok {\n\t\t\treturn nil, fmt.Errorf(\"preprocessed profile contains duplicate edge %+v\", edge)\n\t\t}\n\n\t\td.NamedEdgeMap.ByWeight = append(d.NamedEdgeMap.ByWeight, edge) // N.B. serialization is ordered.\n\t\td.NamedEdgeMap.Weight[edge] += weight\n\t\td.TotalWeight += weight\n\t}\n\n\treturn d, nil\n\n}\n","sourceCodeStart":74,"sourceCodeEnd":103,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/pgo/deserialize.go#L74-L103","documentation":"Thrown when the preprocessed PGO profile contains the same NamedCallEdge (caller + callee + call-site offset triple) more than once. The deserializer detects this via a map lookup before inserting and rejects duplicates to prevent double-counting weights. The %+v formats the full edge struct for identification.","triggerScenarios":"A NamedCallEdge with identical CallerName, CalleeName, and CallSiteOffset appears in two separate edge entries in the profile. The check `d.NamedEdgeMap.Weight[edge]` returns ok=true on the second occurrence.","commonSituations":"A bug in the profile serialization or preprocessing step that emits the same edge twice instead of summing weights. Can also happen if two different source-level call sites resolve to the same offset due to inlining or if the profile was concatenated from multiple runs without deduplication.","solutions":["Regenerate the profile from a single profiling run to avoid duplicate edges from manual concatenation.","If merging profiles, deduplicate edges and sum their weights before serialization.","Inspect the profile for the duplicated edge (identified by the %+v output) and remove the redundant entry.","Report a bug if the Go toolchain's own preprocessing produced the duplicate."],"exampleFix":"// Data fix: if two entries share the same edge, merge them:\n// Before:\n//   caller\ncallee\n42 100\n//   caller\ncallee\n42 200\n// After (summed):\n//   caller\ncallee\n42 300","handlingStrategy":"validation","validationCode":"// Pre-deduplicate edges before serialization:\nfunc deduplicateEdges(edges []NamedCallEdge, weights []int64) ([]NamedCallEdge, []int64) {\n    merged := make(map[NamedCallEdge]int64)\n    for i, e := range edges {\n        merged[e] += weights[i]\n    }\n    uniq := make([]NamedCallEdge, 0, len(merged))\n    uniqW := make([]int64, 0, len(merged))\n    for e, w := range merged {\n        uniq = append(uniq, e)\n        uniqW = append(uniqW, w)\n    }\n    return uniq, uniqW\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate and sum edge weights before serializing a preprocessed profile.","Do not concatenate multiple preprocessed profile files without merging.","Regenerate from a single pprof source if duplicates appear."],"tags":["pgo","deserialization","duplicate-data","go-compiler-internal"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}