🔧 Error Fixes
· 1 min read

fatal error: all goroutines are asleep — deadlock — How to Fix It


fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:

Every goroutine is blocked waiting for something that will never happen. Usually a channel issue.

Fix 1: Unbuffered Channel — No Receiver

// ❌ Writing to channel with no goroutine reading
ch := make(chan int)
ch <- 42  // 💥 Blocks forever, no one is reading

// ✅ Read in a goroutine
ch := make(chan int)
go func() { fmt.Println(<-ch) }()
ch <- 42

Fix 2: Forgot to Close Channel

// ❌ range blocks forever waiting for more values
ch := make(chan int)
go func() {
    ch <- 1
    ch <- 2
    // Forgot close(ch)
}()
for v := range ch {  // 💥 Waits forever after 2
    fmt.Println(v)
}

// ✅ Close the channel when done
go func() {
    ch <- 1
    ch <- 2
    close(ch)
}()

Fix 3: WaitGroup Mismatch

// ❌ Add and Done counts don't match
var wg sync.WaitGroup
wg.Add(2)
go func() { wg.Done() }()
// Only one Done() but Add(2) → wg.Wait() blocks forever

// ✅ Match Add and Done
wg.Add(1)
go func() { defer wg.Done(); doWork() }()
wg.Wait()

Fix 4: Mutex Lock Not Released

// ❌ Lock acquired but never released
var mu sync.Mutex
mu.Lock()
// Forgot mu.Unlock()
mu.Lock()  // 💥 Deadlock

// ✅ Always defer Unlock
mu.Lock()
defer mu.Unlock()

Fix 5: Buffered Channel

// If you need to send without a ready receiver:
ch := make(chan int, 1)  // Buffer size 1
ch <- 42  // Doesn't block
fmt.Println(<-ch)

Debugging

# Get goroutine dump
kill -SIGQUIT <pid>

# Or in code
import "runtime/pprof"
pprof.Lookup("goroutine").WriteTo(os.Stderr, 1)