go runtime_error ai_generated true

fatal error: all goroutines are asleep - deadlock! (blocked on chan receive)

ID: go/fatal-error-all-goroutines-are-asleep-deadlock-blocked-

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

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.18 active — — —
1.21 active — — —
1.23 active — — —

Root Cause

main receives from a channel that no goroutine ever sends to, e.g. a producer goroutine exited early due to an error or a nil channel was used.

generic

中文

main 从某个 channel 接收,但没有任何 goroutine 会向其发送,例如生产者 goroutine 因错误提前退出,或使用了 nil channel。

Workarounds

  1. 94% success
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()
    select {
    case v := <-ch:
        use(v)
    case <-ctx.Done():
        return ctx.Err()
    }
  2. 92% success
    go func() {
        defer close(ch)
        for _, x := range items {
            ch <- x
        }
    }()
    for v := range ch { use(v) }

Dead Ends

Common approaches that don't work:

  1. 85% fail

    Buffer only helps if a sender exists; with no sender, receive still blocks forever.

  2. 90% fail

    An empty select blocks forever too, converting deadlock into a silent hang.