Skip to content

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.