go vet: Catch Bugs Compilers Allow
go vet catches suspicious constructs the compiler ignores, like Printf argument mismatches. Run it in CI to spot concurrency and formatting bugs early. It relies on heuristics, so a clean report does not guarantee correctness and false positives can occur.
WHY IT EXISTS: The Go compiler is conservative by design. It rejects invalid syntax and type errors, but it intentionally ignores many suspicious yet technically legal patterns that almost always indicate bugs. go vet fills this gap by applying heuristics to source code to flag likely mistakes without changing the language specification or slowing down compilation.
THE MENTAL MODEL: Think of go vet as an experienced code reviewer who has memorized dozens of common bug patterns. It does not prove your program is correct; it simply raises its hand when it sees code that looks like a known mistake. Like that reviewer, it sometimes cries wolf and occasionally misses real problems, but it catches enough expensive bugs to be worth consulting on every build.
HOW IT WORKS: Vet inspects Go source code using a suite of checkers that look for specific anti-patterns. These include printf format string mismatches, useless assignments, impossible interface assertions, common sync/atomic mistakes, composite literals without keys, locks erroneously passed by value, lost context cancellation functions, and unreachable code. Each checker is a heuristic pattern matcher, not a formal verifier. The tool is invoked through the go command with go vet for the current package or go vet my/project/... for recursive checks. It exits with a non-zero status if it reports any problem or if invocation fails, and zero otherwise.
WHEN TO USE IT: Run go vet in three places: first, in local pre-commit hooks to catch formatting and concurrency bugs before code review; second, in CI pipelines to block merges that contain suspicious constructs; third, when upgrading Go versions, because new checkers are added each release and old code may surface hidden issues. It is especially valuable for catching printf mismatches, copylocks in struct methods, and loop variable closures in goroutines.
WHEN NOT TO USE IT: Do not treat a clean vet report as proof of correctness. The tool explicitly depends on unreliable heuristics and does not check every possible problem. Do not use it as your only quality gate. It is also not a replacement for unit tests, fuzzing, or race detection. If vet reports a false positive, you may need to suppress or ignore the check rather than rewrite correct code.
ONE CANONICAL EXAMPLE: A team deploys a service that crashes under load because a developer passed a sync.Mutex by value into a struct method, causing the lock state to copy and deadlock. The compiler allows this because the types are valid, but go vet copylocks checker flags the method receiver. Running go vet in CI would have blocked the merge with a clear warning before the bug reached staging.
Read the original → pkg.go.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.