go
runtime_error
ai_generated
true
panic: sync: negative WaitGroup counter
ID: go/negative-waitgroup-counter
80%Fix Rate
90%Confidence
0Evidence
2024-04-15First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 1.x | active | — | — | — |
Root Cause
wg.Done() is called more times than wg.Add(n). Common when Done is deferred in a loop that runs more iterations than Add, or a goroutine calls Done without a matching Add.
generic中文
wg.Done() 调用次数多于 wg.Add(n)。常见于在迭代次数多于 Add 的循环中 defer Done,或有 goroutine 调用 Done 却没有匹配的 Add。
Workarounds
-
95% success
Call Add(1) synchronously before launching each goroutine and defer Done inside: for _, item := range items { wg.Add(1) go func(it Item){ defer wg.Done(); process(it) }(item) } wg.Wait() -
92% success
Use golang.org/x/sync/errgroup which manages the counter correctly: g, ctx := errgroup.WithContext(ctx) for _, it := range items { it := it; g.Go(func() error { return process(ctx, it) }) } return g.Wait()
Dead Ends
Common approaches that don't work:
-
85% fail
Race: Wait() may return before the goroutine has called Add, causing Done to decrement below zero or the wait to miss the goroutine.
-
80% fail
The counter is already corrupted; recover leaves the WaitGroup in an invalid state.