go
runtime_error
ai_generated
true
panic: sync: negative WaitGroup counter
ID: go/negative-waitgroup-counter
80%Fix Rate
88%Confidence
0Evidence
2024-03-11First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 1.16+ | active | — | — | — |
Root Cause
wg.Done() called more times than wg.Add(), commonly when Done is deferred inside a goroutine that also returns early or when Add is called inside the goroutine itself.
generic中文
wg.Done() 的调用次数多于 wg.Add(),通常发生在 goroutine 内 defer Done 且提前返回,或 Add 在 goroutine 内部调用时。
Workarounds
-
95% success
wg.Add(1) go func() { defer wg.Done() doWork() }() wg.Wait() -
92% success
g := new(errgroup.Group) for _, item := range items { item := item g.Go(func() error { return process(item) }) } if err := g.Wait(); err != nil { return err }
Dead Ends
Common approaches that don't work:
-
85% fail
recover cannot catch this panic reliably across goroutine boundaries and masks the real imbalance, causing the Wait() to return prematurely.
-
90% fail
The counter imbalance is structural; sleeping only changes timing and the panic still fires when Done exceeds Add.