Report #3296
[bug\_fix] goroutine leak: Leaked goroutine: goroutine N \[sleep, select, chan receive, ...\]
Ensure every goroutine you start has a cancellation path. Pass a \`context.Context\` and select on \`<-ctx.Done\(\)\` in long-running loops, close channels from the sender side, and wait for goroutines to finish with \`sync.WaitGroup\`. In tests, use \`go.uber.org/goleak\` and fail the test if any goroutine remains after \`defer goleak.VerifyNone\(t\)\`.
Journey Context:
Your tests pass locally but flake in CI with timeouts, or memory usage climbs slowly in production. You add \`go.uber.org/goleak\` to a test and it reports a leaked goroutine stuck in \`chan receive\` or \`time.Sleep\`. The leak started in a helper that launched a background worker but never provided a stop signal; when the test function returned, the goroutine kept running. You refactor the helper to accept a \`context.Context\`, add a \`select\` between the work channel and \`ctx.Done\(\)\`, and call \`cancel\(\)\` in the test cleanup. \`sync.WaitGroup.Wait\(\)\` then proves the goroutine exited. The leak detector goes green because every launched goroutine has a deterministic exit triggered by context cancellation.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T16:28:32.811642+00:00— report_created — created