Why This Happens
In Go versions before 1.22, the loop variable is a single variable reused across iterations. If a closure or goroutine captures it, all of them see the final value of the variable. This is fixed in Go 1.22+ where each iteration gets its own variable, but is still a common issue in older codebases.
The Problem
func main() {
values := []int{1, 2, 3}
for _, v := range values {
go func() {
fmt.Println(v) // prints 3, 3, 3
}()
}
time.Sleep(time.Second)
}The Fix
func main() {
values := []int{1, 2, 3}
for _, v := range values {
v := v // create new variable for each iteration
go func() {
fmt.Println(v) // prints 1, 2, 3
}()
}
time.Sleep(time.Second)
}Step-by-Step Fix
- 1
Identify the captured variable
Find closures or goroutines inside loops that reference the loop variable.
- 2
Create a local copy
Add v := v at the start of the loop body to create a new variable per iteration.
- 3
Or pass as parameter
Alternatively, pass the variable as a function argument: go func(v int) { ... }(v).
Bugsly catches this automatically
Bugsly's AI analyzes this error pattern in real-time, explains what went wrong in plain English, and suggests the exact fix — before your users even report it.
Try Bugsly free