go
runtime_error
ai_generated
true
panic: sync: 负的 WaitGroup 计数器
panic: sync: negative WaitGroup counter
ID: go/negative-waitgroup-counter
80%修复率
88%置信度
0证据数
2024-03-11首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.16+ | active | — | — | — |
根因分析
wg.Done() 的调用次数多于 wg.Add(),通常发生在 goroutine 内 defer Done 且提前返回,或 Add 在 goroutine 内部调用时。
English
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.
解决方案
-
95% 成功率
wg.Add(1) go func() { defer wg.Done() doWork() }() wg.Wait() -
92% 成功率
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 }
无效尝试
常见但无效的做法:
-
85% 失败
recover cannot catch this panic reliably across goroutine boundaries and masks the real imbalance, causing the Wait() to return prematurely.
-
90% 失败
The counter imbalance is structural; sleeping only changes timing and the panic still fires when Done exceeds Add.