go runtime_error ai_generated true

panic: send on closed channel

ID: go/send-on-closed-channel

Also available as: JSON · Markdown · 中文
80%Fix Rate
88%Confidence
0Evidence
2024-02-19First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
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

  1. 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) }()
  2. 92% success
    select {
    case out <- v:
    case <-done:
        return
    }

Dead Ends

Common approaches that don't work:

  1. 85% fail

    The check-then-send is not atomic; a close can land between the check and the send.

  2. 70% fail

    Recover silences the crash but the message is silently dropped; downstream logic may hang waiting for it.