Skip to content
Ownership and lifecycle

cancellationownership

Checks context and signal-derived cancellation functions are called on every return path.

Fix offeredYes

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)
}