Troubleshooting
Scope: the compiler errors and gotchas you'll actually hit, what they mean, and the plain fix for each.
Compiler errors
"declared and not used"
x := 42
// (never use x) → compile error: x declared and not used
Go refuses to compile with unused variables or unused imports. This feels strict until it catches your third typo'd variable.
Fix: use it, or remove it. During debugging, assign to the
blank identifier: _ = x.
"undefined: X" / "cannot refer to unexported name"
You used a name from another package that doesn't exist — or exists but is lowercase (unexported).
Fix: check the spelling and the capitalization. Remember: capital = public across packages.
"mismatched types" / "cannot use X as Y"
Go doesn't implicitly convert between types — not even int to
int64:
var a int = 5
var b int64 = int64(a) // explicit conversion required
Fix: convert explicitly. The compiler tells you exactly which types clashed.
"missing return"
Every code path in a function with a return type must return a value. The compiler checks this.
Fix: add the missing return, often in an else branch you
forgot.
Gotchas (compiles fine, surprises you)
append needs its result assigned
nums := []int{1, 2, 3}
append(nums, 4) // result thrown away — nums unchanged!
nums = append(nums, 4) // correct
append may return a new slice header. Always assign it back.
Loop variable capture (pre-1.22 habit)
Since Go 1.22, loop variables are fresh each iteration, so this classic bug is fixed:
for _, v := range nums {
go func() {
fmt.Println(v) // each goroutine sees its own v (Go 1.22+)
}()
}
If you read old code or old Stack Overflow answers warning about this — that was before Go 1.22. Modern Go is fine.
nil maps vs empty maps
var m map[string]int // nil map: reads fine, writes panic
m["a"] = 1 // PANIC: assignment to entry in nil map
Fix: initialize before writing: m := make(map[string]int)
or m := map[string]int{}. Reading from a nil map is safe
(returns zero values); writing to one crashes.
Comparing with == on slices
Slices can't be compared with == (except against nil).
Fix: compare element by element, or use
slices.Equal(a, b) from the standard library.
Integer division truncates
fmt.Println(7 / 2) // 3, not 3.5
Fix: convert first: float64(7) / 2.
Build/tooling issues
go not found after installing
Reopen your terminal. The installer updates PATH; existing
terminals don't pick it up.
"go.mod not found" / working outside a module
Since Go 1.16, commands like go build and go get expect a
go.mod. Fix: go mod init <name> in your project folder.
(See Your First Program.)
Slow or stuck downloads
go mod download hitting the network can hang behind strict
firewalls. The module proxy (proxy.golang.org) is the default;
your environment may need GOPROXY adjusted — check with whoever
runs your network.
The meta-rule
Go's compiler errors are short and usually point at the exact
line. Read the message literally — it means what it says. And
go vet ./... catches a class of mistakes the compiler allows;
run it before asking for help.
Check
- [ ] You know why
append's result must be assigned - [ ] You can fix "declared and not used" two ways
- [ ] You know the nil-map write panic and its fix
Next: Glossary.