go runtime_error ai_generated true

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

ID: go/waitgroup-wait-race

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

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.18 active — — —
1.22 active — — —

Root Cause

A WaitGroup was reused (Add called) while a previous Wait() had not yet returned, which is explicitly disallowed by the sync package.

generic

中文

在上一轮 Wait() 尚未返回时就再次调用了 Add() 复用 WaitGroup,sync 包明确禁止这种用法。

Workarounds

  1. 95% success
    for _, batch := range batches {
        var wg sync.WaitGroup
        for _, it := range batch {
            wg.Add(1)
            go func(it Item) { defer wg.Done(); process(it) }(it)
        }
        wg.Wait()
    }
  2. 92% success
    for _, stage := range stages {
        g := new(errgroup.Group)
        for _, t := range stage { g.Go(t.Run) }
        if err := g.Wait(); err != nil { return err }
    }

Dead Ends

Common approaches that don't work:

  1. 85% fail

    Recover leaves the WaitGroup in an inconsistent state and the concurrent Wait may return early or hang.

  2. 80% fail

    Two Waits on the same group do not resolve the reuse race; it can still panic.

  3. 90% fail

    Timing-based, non-deterministic, and fails under load.