golang/go · error
preprocessed profile contains duplicate edge %+v
Error message
preprocessed profile contains duplicate edge %+v
What it means
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.
Source
Thrown at src/cmd/internal/pgo/deserialize.go:92
co, err := strconv.Atoi(split[0])
if err != nil {
return nil, fmt.Errorf("preprocessed profile error processing call line: %w", err)
}
edge := NamedCallEdge{
CallerName: callerName,
CalleeName: calleeName,
CallSiteOffset: co,
}
weight, err := strconv.ParseInt(split[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("preprocessed profile error processing call weight: %w", err)
}
if _, ok := d.NamedEdgeMap.Weight[edge]; ok {
return nil, fmt.Errorf("preprocessed profile contains duplicate edge %+v", edge)
}
d.NamedEdgeMap.ByWeight = append(d.NamedEdgeMap.ByWeight, edge) // N.B. serialization is ordered.
d.NamedEdgeMap.Weight[edge] += weight
d.TotalWeight += weight
}
return d, nil
}
View on GitHub (pinned to b6b368adc5)
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.
Example fix
// Data fix: if two entries share the same edge, merge them: // Before: // caller callee 42 100 // caller callee 42 200 // After (summed): // caller callee 42 300
Defensive patterns
Strategy: validation
Validate before calling
// Pre-deduplicate edges before serialization:
func deduplicateEdges(edges []NamedCallEdge, weights []int64) ([]NamedCallEdge, []int64) {
merged := make(map[NamedCallEdge]int64)
for i, e := range edges {
merged[e] += weights[i]
}
uniq := make([]NamedCallEdge, 0, len(merged))
uniqW := make([]int64, 0, len(merged))
for e, w := range merged {
uniq = append(uniq, e)
uniqW = append(uniqW, w)
}
return uniq, uniqW
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- preprocessed profile entry missing weight
- preprocessed profile entry got %v want 2 fields
- preprocessed profile error processing call line: %w
- preprocessed profile error processing call weight: %w
- error parsing profile: %w
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/77277d2f9f8c8bcc.
Report an issue: GitHub.