go
runtime_error
ai_generated
true
panic: send on closed channel
ID: go/send-on-closed-channel
80%Fix Rate
88%Confidence
0Evidence
2024-02-19First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 1.19 | active | — | — | — |
| 1.20 | active | — | — | — |
| 1.22 | active | — | — | — |
Root Cause
A producer goroutine sends to a channel after another goroutine has closed it. Usually a close in a defer while sibling producers are still running.
generic中文
生产者 goroutine 在另一个 goroutine 关闭 channel 后仍发送数据。通常是 defer 中的 close 与仍在运行的兄弟生产者竞争。
Workarounds
-
97% success
var wg sync.WaitGroup for i := 0; i < n; i++ { wg.Add(1) go func(id int) { defer wg.Done() for v := range src(id) { out <- v } }(i) } go func() { wg.Wait(); close(out) }() -
92% success
select { case out <- v: case <-done: return }
Dead Ends
Common approaches that don't work:
-
85% fail
The check-then-send is not atomic; a close can land between the check and the send.
-
70% fail
Recover silences the crash but the message is silently dropped; downstream logic may hang waiting for it.