# panic: send on closed channel

- **ID:** `go/channel-send-on-closed-channel`
- **Domain:** go
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

A goroutine executed ch <- val after another goroutine called close(ch). Sending on a closed channel always panics; the race between sender and closer is the root issue.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.0+ | active | — | — |

## Workarounds

1. **** (95% success)
   ```
   done := make(chan struct{})
// producer owns close
func producer(ch chan int, done <-chan struct{}) {
    defer close(ch)
    for i := 0; ; i++ {
        select {
        case <-done:
            return
        case ch <- i:
        }
    }
}
   ```
2. **** (90% success)
   ```
   select {
case ch <- v:
case <-quit:
    return
}
   ```

## Dead Ends

- **** — recover only stops the panic in the current goroutine; the send is logically invalid and the message is silently lost, corrupting downstream logic. Also recover does not work across goroutine boundaries. (90% fail)
- **** — Sleep does not establish happens-before ordering; the scheduler may still run the closer after the sender. It only narrows the race window and fails under load. (85% fail)
