go
runtime_error
ai_generated
true
panic: send on closed channel
ID: go/channel-send-on-closed
80%Fix Rate
90%Confidence
0Evidence
2024-03-11First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 1.0+ | active | — | — | — |
Root Cause
A goroutine calls ch <- v after another goroutine has already called close(ch). Go panics immediately because sending to a closed channel is always a programming error, unlike receiving which returns the zero value.
generic中文
某个 goroutine 在另一个 goroutine 已调用 close(ch) 之后执行 ch <- v。Go 会立即 panic,因为向已关闭 channel 发送永远是编程错误,而接收则会返回零值。
Workarounds
-
92% success
Make the sender the only owner of close. Use a done channel and select so senders never write after shutdown: select { case ch <- v: case <-done: return } -
80% success
Use sync.Once for close and guard sends with a mutex + closed flag: mu.Lock() if !closed { ch <- v } mu.Unlock()
Dead Ends
Common approaches that don't work:
-
90% fail
recover() only works in the same goroutine that is panicking, and even then it hides the race; the underlying close/send race remains and data is silently lost.
-
85% fail
select default does not protect against a closed channel; a send case on a closed channel still panics when selected.