Loop variable captured by a goroutine or defer closure
Part of Code Quality & Syntax, which counts for 20% of the overall score. When this check fires it deducts 4 points from that category, once per scan, no matter how many places it turns up.
What it detects
A go or defer closure declared with no parameters, launched from inside a for/range loop, references the loop variable directly instead of receiving it as an argument. Heuristic: Go 1.22 made loop variables per-iteration, so this matters most for modules still targeting an older Go version, and is otherwise a readability nit.
Why it matters
A go or defer closure that takes no parameters and references a loop variable directly, instead of receiving it as an argument, can end up running after the loop has moved on or finished, at which point the variable may hold its final value from the last iteration rather than the value it had when the closure was created. Before Go 1.22 this was one of the most common real-world Go bugs; with Go 1.22's per-iteration loop variables it is far less likely to bite, but explicitly passing the value in remains the clearer, version-independent way to write it.
How to fix it
Pass the loop variable into the closure as a parameter instead of relying on it being captured correctly: go func(v T) { use(v) }(v) or defer func(v T) { use(v) }(v). This makes the intended value explicit regardless of which Go version the module targets.
The paid report includes a ready-to-paste prompt for your AI coding agent for every check it finds, pointed at the exact findings from your scan. See pricing
Does your repo trip this check?
Paste a GitHub URL or drop a project folder. Scans run in your browser and take seconds.
Scan your repo