go runtime_error ai_generated true

panic: sync: WaitGroup is reused before previous Wait has returned

ID: go/waitgroup-added-after-wait

Also available as: JSON · Markdown · 中文
80%Fix Rate
88%Confidence
0Evidence
2024-04-22First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.0+ active

Root Cause

wg.Add() was called from a goroutine while another goroutine was blocked in wg.Wait(), or the WaitGroup was reused across batches without synchronization.

generic

中文

在一个 goroutine 阻塞于 wg.Wait() 期间,另一个 goroutine 调用了 wg.Add(),或 WaitGroup 在未同步的情况下跨批次重用。

Workarounds

  1. 97% success
    var wg sync.WaitGroup
    for _, item := range items {
        wg.Add(1)
        go func(it Item) {
            defer wg.Done()
            process(it)
        }(item)
    }
    wg.Wait()
  2. 93% success
    for _, batch := range batches {
        var wg sync.WaitGroup
        for _, x := range batch {
            wg.Add(1)
            go func(v X) { defer wg.Done(); work(v) }(x)
        }
        wg.Wait()
    }

Dead Ends

Common approaches that don't work:

  1. 75% fail

    The ordering of Add vs Wait is the actual constraint; moving Wait just changes where the race manifests and can cause premature return.

  2. 80% fail

    No happens-before guarantee; under load the Add still races with Wait.