go runtime_error ai_generated true

fatal error: all goroutines are asleep - deadlock! (select with no ready case)

ID: go/select-blocked-forever-no-default

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

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.x active — — —

Root Cause

A select with multiple channel cases blocks forever because no case is ever ready and there is no default or timeout. Often a producer/consumer wiring mistake where the expected channel is never written.

generic

中文

含多个 channel 分支的 select 因没有任何分支就绪、且无 default 或超时,永久阻塞。常为生产者/消费者接线错误,预期的 channel 从未被写入。

Workarounds

  1. 90% success
    Add a context or timeout case to break the block and surface the bug:
    select {
    case v := <-ch:
        use(v)
    case <-ctx.Done():
        return ctx.Err()
    case <-time.After(30 * time.Second):
        return errors.New("select timeout")
    }
  2. 85% success
    Verify the producer actually sends on the expected channel and that the channel is not nil (sending to a nil channel blocks forever).

Dead Ends

Common approaches that don't work:

  1. 80% fail

    Turns the blocking select into a busy spin that burns CPU and still never handles the missing event.

  2. 70% fail

    If the root wiring is wrong, extra cases don't become ready and the deadlock persists.