BETA Shoulder is in beta — Findings may sometimes be wrong. Your feedback shapes what we fix next. Share feedback
Rules / Go

WaitGroup Misuse

Description

Improper use of sync.WaitGroup can cause race conditions, panics, or deadlocks. Common issues include calling Add() inside goroutines and Done() count mismatches.

What Shoulder detects

Improper WaitGroup usage can cause: - Race conditions (Add inside goroutine) - Panics (negative counter from Done miscount) - Deadlocks (Wait before Add completes)

How to fix

1. Always Add() BEFORE starting goroutine:
```go
wg.Add(1)
go func() {
    defer wg.Done()
    // work
}()
```

2. Always use defer wg.Done() to ensure it runs:
```go
go func() {
    defer wg.Done()  // Runs even if panic occurs
    work()
}()
```

3. Consider using errgroup for better error handling:
```go
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
    return work()
})
err := g.Wait()
```

Applies to

Languages

References

Scan for this issue

Detect with Shoulder CLI
npx @shoulderdev/cli trust --rule=go-waitgroup-misuse .

Related rules