go runtime_error ai_generated true

panic: send on closed channel

ID: go/channel-send-on-closed-channel

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

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
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

  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

Common approaches that don't work:

  1. 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.

  2. 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.