Skip to main content
Code Smells

Stop Hunting Bugs: Why Code Smells Are Your Review's Real Target

Code review isn't about catching bugs—it's about stopping code smells. Here's how to shift your focus and improve code health.

The 80% Illusion

When I first started reviewing code, I hunted for bugs like a bloodhound. I'd scan every conditional, trace every loop, and mentally execute every function in my head. But here's the thing: at Google, where they analyzed over 9 million code reviews, they found that finding bugs isn't the primary purpose of review. The real value lies elsewhere (Modern Code Review: A Case Study at Google, ICSE-SEIP '18).

So what is that value? It's catching code smells—those subtle design flaws and maintainability traps that don't break the build today but will haunt you tomorrow. If you're only looking for functional bugs, you're missing the point. And I'm not just talking about style preferences; I'm talking about the stuff that makes your codebase rot from the inside.

My thesis is simple: Code review should be primarily a code smell detection exercise, not a bug hunt. Bugs are transient and often caught by tests, but code smells are persistent and multiply. They're the silent killers of software projects.

Why the Bug Hunt Fails

Here's the inconvenient truth: bugs are hard to spot in review. Researchers at Microsoft found that while finding defects is the main motivation for review, the actual outcomes are more about knowledge transfer and team awareness (Bacchelli & Bird, ICSE 2013). And the Google study backs this up: fewer than 25% of changes had more than one reviewer, and over 80% of reviews finished in a single iteration. That's not enough eyeballs to catch subtle concurrency issues.

But code smells? They're visible. They're structural. They're the kind of thing that static analysis tools can flag, but a human eye can catch even better. Take cyclomatic complexity—SonarQube defines it as the number of paths through code, calculated as 1 + number of conditional branches. A function with a complexity of 50 is a nightmare to test and maintain, but it won't necessarily fail a test. It's a smell.

And here's the kicker: code smells are more dangerous than bugs. A bug is a one-off mistake; a smell is a systemic issue that generates bugs over time. Over-engineering, for example, is a smell that Google explicitly warns reviewers to be vigilant about—code made more generic than needed, solving problems that don't exist yet (Google Engineering Practices). That kind of complexity is a breeding ground for future bugs.

The Smell-First Review Framework

So how do you actually do this? It's not about throwing out bug hunting; it's about reordering your priorities. Google's own guidance says the most important thing to cover in a review is the overall design of the change, before functionality, complexity, tests, and naming (Google Engineering Practices). That's a smell-first approach.

Here's my practical framework, which I use in every review:

  • Step 1: Read the change description and the diff at a high level. Ask: Does this design make sense? Does it fit the existing architecture?
  • Step 2: Look for specific smells: duplicated code, overly long functions, excessive nesting, magic numbers, and premature abstraction.
  • Step 3: Only then drill into logic for bugs, edge cases, and concurrency issues.

This doesn't mean you ignore bugs. Google's review checklist still includes thinking about edge cases and concurrency problems, which are hard to catch by just running the code (Google Engineering Practices). But you'll find more long-term value in spotting a code smell than in catching a null pointer exception.

The Counter-Argument: We Need to Ship Fast

You might be thinking: "This is all well and good, but we have deadlines. We need to ship, not polish." I've heard that a thousand times. The counter-argument is that focusing on smells slows down reviews and delays launches.

But here's what the data says: at Google, the median change size is about 24 lines, and the median time to first feedback is under 1 hour for small changes. That's not slow. And Google's own engineering practices state that the primary purpose of review is to ensure the overall code health of the codebase is improving (Google Engineering Practices). If you let a smell through to save an hour, you're trading a short-term gain for a long-term pain.

What about emergency fixes? Google defines an emergency as a change that fixes a major security hole or lets a launch continue instead of rolling back—those get expedited review, but even then, Google says to review them again more thoroughly after the emergency is resolved (Google Engineering Practices). So even in emergencies, they don't sacrifice long-term health.

And let's be honest: most deadlines are soft. As Google puts it, launching a week later than planned is not an emergency, and code health should not be sacrificed to meet soft deadlines (Google Engineering Practices). If you're shipping smells because of a soft deadline, you're making a bad trade.

The Numbers Don't Lie

Still skeptical? Let me hit you with some numbers. SonarQube's default maintainability rating scale is based on technical debt ratio: A is ≤5%, B is 5-10%, C is 10-20%, D is 20-50%, and E is >50% (SonarQube). A codebase that's rated E is a disaster zone. And technical debt is measured in remediation time—it's real, tangible cost.

Now, compare that to the cost of a bug. A bug might take hours to fix, but a code smell like a 50-complexity function will take days to refactor, and it will keep generating bugs while it's there. The return on investment for catching smells in review is enormous.

And here's a comparison that might surprise you: Google's research found that 97% of developers were satisfied with their review tool, and the key expectations were education, maintaining norms, gatekeeping, and accident prevention (Modern Code Review: A Case Study at Google). Notice what's not on that list? "Finding bugs." That's because bugs are a byproduct; smells are the disease.

How to Make It Work in Practice

So, how do you shift your review culture? First, stop reviewing line-by-line for style. Let automation handle that—linters, formatters, and static analyzers should catch style and mechanical issues (Google Engineering Practices). Save your brainpower for design and smells.

Second, use a checklist. I keep one that includes: Is there duplication? Are functions doing too much? Is there over-engineering? Are there magic numbers? Is the code harder to read than it needs to be? These are the things that matter.

Third, and this is crucial: when you find a smell, don't just say "fix it." Offer a solution. Google's guidance on review comments says to offer solutions rather than just problems, and to label severity (Google Engineering Practices). A comment like "This function has a cyclomatic complexity of 30; consider breaking it into smaller pieces" is actionable.

Finally, remember that small PRs are your friend. Google recommends keeping changes under 400-500 lines, and their own data shows that the median change is around 24 lines (Google Engineering Practices; Modern Code Review). Small changes are easier to review thoroughly, and smell detection is more effective when you can see the whole picture.

The Bottom Line

Code review is not a bug hunt. It's a quality gate, a teaching tool, and a chance to stop the rot before it starts. By focusing on code smells, you'll improve code health, reduce technical debt, and actually make your codebase better over time. And that's the whole point.

The single most important thing to remember: Review for the code you'll have in a year, not the bug you might catch today.

Sources

  • Modern Code Review: A Case Study at Google (ICSE-SEIP '18) - https://www.papercache.org/papers/mlsys/system/2026/03/25/modern-code-review-a-case-study-at-google
  • Google Engineering Practices - What to look for in a code review - https://google.github.io/eng-practices/review/reviewer/looking-for.html
  • SonarQube Server Docs - Understanding measures and metrics - https://docs.sonarsource.com/sonarqube-server/user-guide/code-metrics/metrics-definition
  • Modern Code Review: Expectations, Outcomes, and Challenges (Bacchelli & Bird, ICSE 2013) - https://www.microsoft.com/en-us/research/publication/expectations-outcomes-and-challenges-of-modern-code-review/
  • Google Engineering Practices - Standard of Code Review - https://google.github.io/eng-practices/review/reviewer/standard.html

Share this article:

Comments (0)

No comments yet. Be the first to comment!