go
runtime_error
ai_generated
true
panic: sync: negative WaitGroup counter
ID: go/sync-waitgroup-negative-counter
80%Fix Rate
89%Confidence
0Evidence
2024-02-14First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 1.x | active | — | — | — |
Root Cause
wg.Done() is called more times than wg.Add(n), often because Done is called in a goroutine that was never added, or Add is called after Wait has already returned.
generic中文
wg.Done() 调用次数大于 wg.Add(n),常见于在未 Add 的 goroutine 中调用 Done,或 Wait 返回后才调用 Add。
Workarounds
-
97% success
for _, item := range items { wg.Add(1) go func(it Item) { defer wg.Done() process(it) }(item) } wg.Wait() -
95% success
g, ctx := errgroup.WithContext(ctx) for _, it := range items { it := it g.Go(func() error { return process(ctx, it) }) } if err := g.Wait(); err != nil { return err }
Dead Ends
Common approaches that don't work:
-
70% fail
Race with wg.Wait(): Wait may return before Add runs, then Done panics or Wait returns early.
-
75% fail
Hides the bug; the WaitGroup is now inconsistent and Wait may hang or return prematurely.