Ownership and lifecycle
cancellationownership
Checks context and signal-derived cancellation functions are called on every return path.
What it detects
Tracks cancel functions returned by context and signal helpers and reports any successful return path that neither calls the cancel function nor transfers it to the caller.
Checks
| Check | What it detects |
|---|---|
release |
Reports derived cancel functions that are neither called nor transferred on every return path. |
Why this is flagged
A derived context can retain timers, memory, and references to its parent until it is canceled. Calling the cancel function promptly releases those resources and tells dependent work to stop.
Further reading: Package context.
How to fix it
Keep the cancel function returned when the context is created. Usually, call
defer cancel() immediately after checking that creation succeeded, or call it
explicitly at the point where the derived work is finished.
Examples
Flagged code
func work(parent context.Context) { // gohawk: cancel function from context.WithCancel is not called on every return path ctx, cancel := context.WithCancel(parent) _ = cancel doWork(ctx)}Accepted code
func workSafely(parent context.Context) { ctx, cancel := context.WithCancel(parent) defer cancel() doWork(ctx)}