go
runtime_error
ai_generated
true
panic: send on closed channel
ID: go/channel-send-on-closed-channel
80%Fix Rate
90%Confidence
0Evidence
2024-02-11First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 1.0+ | active | — | — | — |
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.
generic中文
某个 goroutine 在另一个 goroutine 调用 close(ch) 之后仍执行 ch <- val。向已关闭 channel 发送数据必定 panic,发送方与关闭方之间的竞态是根本原因。
Workarounds
-
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: } } } -
90% success
select { case ch <- v: case <-quit: return }
Dead Ends
Common approaches that don't work:
-
90% fail
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.
-
85% 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.