channelsafety
Checks channel operations for use after close.
What it detects
Reports sends reachable after the same channel has been closed.
Closes and sends inside helpers count too, including helpers in other packages, so a close in one call is matched to a later send on the same channel. The diagnostic points at the send, with the close as a related location.
The full list of precision boundaries, with the fixtures that pin each one, is in the channelsafety design notes.
Checks
| Check | Tier | Kind | What it detects |
|---|---|---|---|
send-after-close |
core | defect | Reports sends reachable after a channel has been closed. |
Why this is flagged
Sending on a closed channel is a run-time panic, not an error a caller can recover from in the normal flow, so a reachable send-after-close is a latent crash. It usually means two parts of the code disagree about which one owns closing the channel.
Further reading: The Go Programming Language Specification: Close.
How to fix it
Move the close after the final send or separate the channel lifetimes.
Examples
Flagged code
func sendAfterClose() { events := make(chan int) close(events) // gohawk: send follows close of channel events <- 1}Accepted code
func deferredCloseAfterSends(values []int) <-chan int { events := make(chan int) go func() { defer close(events) for _, value := range values { events <- value } }() return events}