Skip to main content
Pull Request Pitfalls

The Arthive Craft: Avoiding Review Blindness in Your Pull Request

Every developer has experienced the sinking feeling of merging a pull request, only to discover a bug that was staring everyone in the face during review. It wasn't malice or laziness—it was review blindness. That cognitive phenomenon where your brain fills in gaps, skips over familiar patterns, and assumes the code is correct because it looks similar to what you expected. At Arthive, we've seen this pattern trip up teams of all sizes. The fix isn't more meetings or longer checklists; it's a deliberate craft. This guide will help you recognize review blindness, understand why it happens, and adopt techniques to counteract it—so your reviews catch real issues, not just typos. 1. Who This Affects and What Goes Wrong Without It Review blindness doesn't discriminate. It affects junior developers who defer to senior code, senior engineers who skim familiar patterns, and even the original author who re-reads their own diff.

Every developer has experienced the sinking feeling of merging a pull request, only to discover a bug that was staring everyone in the face during review. It wasn't malice or laziness—it was review blindness. That cognitive phenomenon where your brain fills in gaps, skips over familiar patterns, and assumes the code is correct because it looks similar to what you expected. At Arthive, we've seen this pattern trip up teams of all sizes. The fix isn't more meetings or longer checklists; it's a deliberate craft. This guide will help you recognize review blindness, understand why it happens, and adopt techniques to counteract it—so your reviews catch real issues, not just typos.

1. Who This Affects and What Goes Wrong Without It

Review blindness doesn't discriminate. It affects junior developers who defer to senior code, senior engineers who skim familiar patterns, and even the original author who re-reads their own diff. The problem is universal, but the consequences vary. A missed null check might cause a minor production error; a overlooked permission escalation could become a security incident. Without deliberate countermeasures, teams accumulate technical debt and incident post-mortems that read like a broken record: 'The bug was visible in the PR, but nobody saw it.'

Consider a typical scenario: A developer submits a PR that refactors a payment processing module. The diff shows 200 lines changed, but the core logic shift—an inverted condition—appears as a single-line change buried in a large block. Reviewers focus on the structural changes, assume the logic is the same, and approve. The bug reaches production and charges users incorrectly. This isn't a failure of skill; it's a failure of attention allocation. The cognitive load of understanding the broader refactor leaves little bandwidth to scrutinize the one line that matters.

What goes wrong without a structured approach? Three things: First, reviewers develop 'diff fatigue'—they scan rather than read. Second, they fall into confirmation bias, looking for evidence that the code is correct rather than seeking flaws. Third, they rely on memory of the previous version, which is often incomplete or biased. The result is a review that validates the author's intent rather than the code's correctness. Teams that ignore review blindness often see a pattern: the same developer catches the same type of bug repeatedly, while other reviewers miss it. That's a signal, not a coincidence.

The cost is measurable: delayed deployments, hotfixes, and eroded trust in the review process. But the fix is not to review more aggressively or to demand perfection. It's to change how you read diffs. This guide will show you how.

2. Prerequisites and Context to Settle First

Before you can beat review blindness, you need the right mindset and environment. This section covers what to establish before diving into techniques. First, accept that you are biased. Every reviewer carries assumptions: the author is competent, the tests pass, the architecture is sound. These assumptions are necessary for productivity but dangerous for accuracy. The goal is not to eliminate bias—that's impossible—but to interrupt its automatic influence.

Second, you need a review culture that values questions over speed. If your team measures review time as a productivity metric, reviewers will rush and miss defects. Instead, encourage reviewers to ask 'why' and to challenge assumptions. A simple cultural shift—praising reviewers who find subtle bugs, not just those who approve quickly—can reduce review blindness over time. You also need a consistent process. Sporadic reviews with no structure are more prone to blind spots. Establish a standard workflow: review the description first, then the tests, then the diff, then the context files. That order matters.

Third, use tools to surface hidden changes. Many platforms (GitHub, GitLab, Bitbucket) offer diff settings like 'hide whitespace' or 'split view.' These are useful but can also hide important changes. For example, a line that only changed indentation might be collapsed, but the actual logic change in the same line is invisible. Train yourself to toggle these settings intentionally, not to rely on defaults. Also, consider using linters and static analysis integrated into CI—they catch obvious issues before humans even see the diff, freeing your brain to focus on higher-level concerns.

Finally, understand the limits of your attention. Research in cognitive psychology suggests that focused attention can only be sustained for about 20-30 minutes before performance degrades. If your review takes longer, break it into sessions. Set a timer, review for 25 minutes, then take a break. This prevents the mental fatigue that exacerbates review blindness.

3. Core Workflow: A Step-by-Step Process to Counteract Blindness

This workflow is designed to force you to see what you'd normally skip. It's not a rigid script, but a sequence of deliberate actions that interrupt automatic processing. Follow these steps for every PR you review.

Step 1: Read the PR Description and Commits First

Before looking at any code, read the author's description and the commit messages. Understand the intent: what problem does this solve? What approach does it take? This primes your brain with expectations—but also sets up a trap. The trap is that you'll look for evidence that the code matches the description. To counter that, write down one or two specific things you expect to see (e.g., 'a new validation function' or 'a changed API endpoint'). Then, as you review, actively look for discrepancies.

Step 2: Review the Tests Before the Code

This is the most effective antidote to review blindness. By reading tests first, you see the expected behavior without being influenced by the implementation. Does the test cover edge cases? Are there missing test cases for failure modes? If the tests are incomplete, you've already found a problem. Then, when you read the code, you're testing whether it satisfies the test expectations—a more objective stance.

Step 3: Read the Diff in a Specific Order

Start with the most critical files: configuration, security, data flow. Then move to business logic, then utilities. Resist the urge to read from top to bottom. Instead, prioritize by risk. Use the 'split view' initially to see both old and new versions, but then switch to 'unified view' to spot line-level changes more clearly. Read each line deliberately—don't skim. If you find yourself reading without comprehension, stop and take a break.

Step 4: Use a Personal Checklist

Create a short checklist of common blind spots: off-by-one errors, missing error handling, hardcoded values, security exposures (e.g., SQL injection, XSS), and logging of sensitive data. For each review, mentally or physically check these items. Over time, this becomes habit, but initially it forces you to look for specific patterns.

Step 5: Review in a Different Environment

If possible, pull the branch and run the code locally. This gives you a fresh perspective and lets you test edge cases that the automated tests might miss. Even a quick manual test can reveal issues invisible in a diff.

4. Tools, Setup, and Environment Realities

Your tools can either amplify or reduce review blindness. Here's how to configure them for maximum vigilance.

Diff View Settings

Most platforms default to hiding whitespace changes. That's useful for ignoring formatting noise, but it can also hide real changes that happen to be on the same line as whitespace edits. The fix: toggle whitespace visibility on and off during your review. Start with whitespace hidden to focus on logic, then toggle it on to check for unintended changes (e.g., accidental deletion of a space that breaks a string). Similarly, use 'ignore move detection' sparingly—it can hide that a function was renamed but its body subtly altered.

Linters and Static Analysis

Integrate linters (ESLint, Pylint, RuboCop) and static analysis (SonarQube, CodeQL) into your CI pipeline. These catch style issues, potential bugs, and security vulnerabilities automatically. The benefit for review blindness: they reduce the noise of trivial issues, letting you focus on logic and design. But beware of alert fatigue—if your tool generates too many false positives, reviewers start ignoring it. Tune the rules to your project's needs.

Code Review Platforms

GitHub's 'pull request review' interface allows commenting on lines and grouping feedback. Use this to document your thought process as you go. One technique: after reading a file, leave a comment summarizing your understanding. This forces you to articulate what you saw, which can reveal gaps in your comprehension. Also, use the 'request changes' feature sparingly—it's for blocking issues, not for style preferences. Overusing it can desensitize reviewers to its importance.

Environment Considerations

If your team works in a monorepo, PRs can be large and overwhelming. Break them into smaller, focused changes. A PR that touches 10 unrelated files is harder to review than 10 small PRs. Encourage authors to split changes logically: one PR for refactoring, another for new features. This reduces cognitive load and lowers the chance of review blindness.

5. Variations for Different Constraints

Not every team or project can follow the same workflow. Here are adaptations for common constraints.

Small Teams with No Dedicated Reviewer

If you're the only reviewer, you're especially vulnerable to blindness because you have no second pair of eyes. Mitigate this by using a time delay: review the PR, then wait a few hours or a day before merging. This allows your brain to reset. Also, use the 'review in a different context' technique—review the code on a different device or at a different time of day. Another trick: read the diff out loud. Verbalizing forces you to process each line.

Large Codebases with High Churn

In rapidly changing codebases, reviewers often feel overwhelmed and fall back on trust. To counter this, use a 'risk-based review' approach: focus on files that changed in security-sensitive areas, data models, or external interfaces. For low-risk changes (e.g., UI tweaks), a lighter review might be acceptable. But document this prioritization so it's transparent.

Distributed Teams Across Time Zones

Asynchronous reviews can suffer from context loss. To combat review blindness, require the author to provide a clear description and, if possible, a short screen recording or demo. This gives reviewers a mental model before they see code. Also, use threaded discussions to capture questions and decisions—this builds a shared understanding that reduces blind spots.

Urgent Hotfixes

When time is critical, review blindness is most dangerous. For hotfixes, enforce a mandatory review even if it's just one person. Use a simplified checklist: does the fix address the root cause? Does it break anything obvious? Is there a test? After deployment, schedule a follow-up review to catch anything missed.

6. Pitfalls, Debugging, and What to Check When It Fails

Even with the best process, review blindness can still strike. Here are common pitfalls and how to debug them.

The 'Looks Good to Me' Trap

You read the diff, it seems fine, you approve. Later, a bug emerges. What went wrong? You likely fell into 'satisficing'—accepting a solution that is good enough rather than correct. To debug, ask yourself: did I actually understand every changed line? If you can't explain the change in one sentence, you probably skimmed. The fix: after your review, write a brief summary of the change and the reasoning. If you can't, you didn't review thoroughly.

Overreliance on Tests

Tests are great, but they can also create a false sense of security. If tests pass, reviewers assume the code is correct. But tests can be missing, incorrect, or not covering the relevant scenario. When a review fails, check whether the tests actually test the changed behavior. A common pattern: the test suite passes because the tests are too weak (e.g., testing a function's return type but not its logic).

Reviewing in a Silo

If you review alone, you miss the benefit of discussion. When a bug slips through, consider whether a quick synchronous chat could have caught it. For complex changes, pair review (two people reviewing together) can surface blind spots. Even a brief async comment thread can help.

What to Check When a Bug Is Found Post-Merge

First, don't blame the reviewer—blame the process. Conduct a lightweight post-mortem: was the bug visible in the diff? Was it in a file that was skipped? Was it hidden by a tool setting? Was the reviewer fatigued? Use these insights to adjust your workflow. For example, if the bug was in a whitespace-collapsed line, change your default diff view to show all changes. If it was in a large PR, enforce a size limit.

7. Common Mistakes and a Prose FAQ

Even experienced reviewers make the same mistakes repeatedly. Here are the most common ones and how to avoid them.

Mistake 1: Reviewing in the same order every time. Your brain builds a pattern, and pattern recognition leads to blindness. Mix it up: start with tests one day, with the diff another day, or with the most complex file first.

Mistake 2: Ignoring the PR description. The description is your map. Without it, you're navigating blind. Always read it, and compare it to the actual changes. If they don't match, that's a red flag.

Mistake 3: Approving without running the code. Even a quick local run can reveal issues like missing dependencies, incorrect imports, or runtime errors. If you can't run it locally, at least check the CI logs for warnings.

Mistake 4: Focusing only on logic, not on data flow. A function might be correct in isolation but cause issues when called from a different context. Trace the data flow: what inputs does this change accept? What outputs does it produce? Are there side effects?

Mistake 5: Being too polite to ask questions. If something is unclear, ask. It's better to ask a 'dumb' question than to merge a bug. A question might reveal that the author also didn't fully understand the change.

Now, a few frequently asked questions in prose form.

How do I know if I'm suffering from review blindness? A common sign is that you often find bugs after merging, not during review. Another is that you approve PRs quickly and then feel uneasy later. If you can't recall specific details of a PR you reviewed yesterday, you likely skimmed.

What if my team doesn't have time for a thorough review? Prioritize. Not every PR needs the same depth. For high-risk changes (security, payments, data), invest more time. For low-risk changes (cosmetic, docs), a lighter review is acceptable. But be explicit about the risk level.

Can automation replace human review? No. Tools catch syntax and some logic errors, but they can't understand intent, design trade-offs, or business context. Human review is essential for catching semantic errors and ensuring the change fits the system architecture.

8. What to Do Next: Specific Actions

Reading about review blindness is the first step. The second is to act. Here are three concrete things you can do starting today.

First, build your personal review checklist. Write down 5-10 items that you commonly miss. For example: 'Check for hardcoded sensitive data', 'Verify error handling in all branches', 'Look for off-by-one in loops'. Print it or keep it as a browser tab. Use it for every PR for the next two weeks.

Second, change your default diff settings. Turn off 'hide whitespace' and 'ignore moves' for the first pass. Then, if the diff is noisy, toggle them on selectively. This ensures you see every change at least once.

Third, adopt the 'tests-first' review order. For the next five PRs you review, force yourself to read the test files before the implementation. Note any differences in what you catch. You'll likely find more issues in the tests and in the logic.

Finally, share this article with your team and discuss which technique you'll try together. Review blindness is a team problem, and a team solution is more sustainable. Start small, measure your success by the bugs you catch in review (not just after merge), and refine your process over time.

Share this article:

Comments (0)

No comments yet. Be the first to comment!