| Loop variable capture (pre-1.22) |
Goroutines all print the same value |
Upgrade go directive, or copy the var explicitly each iteration |
Slice aliasing via append |
Silent data corruption under specific cap conditions |
Full slice expressions (s[:n:n]) or explicit copy when handing off sub-slices |
| Nil interface holding a nil pointer |
err != nil is true for a "nil" error |
Return nil explicitly, never a typed nil pointer, from error-returning functions |
| Writing to a nil map |
Panic: assignment to entry in nil map |
Always make() a map before writing |
| Goroutine leak |
Steadily climbing goroutine count |
Every goroutine takes a context.Context or done channel; expose NumGoroutine() as a metric |
Forgetting defer resp.Body.Close() |
Leaked connections, eventual pool exhaustion |
Always defer Close() immediately after checking the error |
| Data race on a shared map/counter |
Rare panics or corrupted state under load |
Run tests and staging traffic with -race; guard with sync.RWMutex or sync/atomic |
No http.Server timeouts |
Slow/malicious clients hold connections open indefinitely |
Set ReadTimeout/WriteTimeout/IdleTimeout explicitly |
range-copying large struct elements |
Mutations inside a range loop silently don't stick |
Index into the slice (items[i].Field = ...) instead of mutating the loop variable |