# goroutine leak: runtime.NumGoroutine() grows unbounded; pprof shows goroutines blocked in chan send

- **ID:** `go/goroutine-leak-runtime-numgoroutine-grows-unbounded-ppro`
- **Domain:** go
- **Category:** resource_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

Producer goroutines block forever on an unbuffered channel because the consumer returned early (error/timeout) and nobody drains the channel.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.19 | active | — | — |
| 1.21 | active | — | — |
| 1.23 | active | — | — |

## Workarounds

1. **** (95% success)
   ```
   go func() {
    defer close(out)
    for _, x := range items {
        select {
        case out <- x:
        case <-ctx.Done():
            return
        }
    }
}()
   ```
2. **** (88% success)
   ```
   defer func() {
    for range out {}
}()
   ```

## Dead Ends

- **** — Delays the leak; once the buffer fills under sustained load the goroutines block again. (80% fail)
- **** — GC does not collect blocked goroutines; they remain referenced by the scheduler. (95% fail)
