How to Fix Any Bug

How to Fix Any Bug

Debugging Scroll Issues in Web Applications — A Systematic Approach

image

Preface

Do you often pass your source code directly to an AI when debugging issues?

Here’s a real case from my web app development experience — a scroll function that broke after adding a network request — and how I systematically identified and resolved it.

---

The Case

While building a small web app feature — a sequence of cards with "scroll to next" buttons — everything worked smoothly until I added an action on the button to send a request to the server.

Immediately, scroll behavior became jerky, stuttery, and sometimes failed entirely.

Suspecting React Router’s re-rendering triggered by the `action`, I initially thought data refreshing might be the cause. But since fetched data was identical, the page shouldn’t visibly change.

In React, re-renders typically shouldn’t break scrolling — so perhaps the issue lay deeper:

  • My own code?
  • React Router?
  • React itself?
  • Browser behavior?

---

Step 0 — Attempt a Direct Fix

I first asked Claude (AI assistant) to fix it:

  • Refactored the `useEffect` condition around `scrollIntoView` — claimed fixed, but wasn’t.
  • Switched from smooth to instant scroll — still broken.

Claude repeatedly reported “Bug fixed” — but the stutter persisted.

💡 Lesson: Many engineers — human or AI — make the same mistake: jumping to “fixes” without confirming they actually solve the problem.

---

Step 1 — Establish a Reliable Reproduction Case (Repro)

A Repro is a repeatable test scenario for verifying if a bug still exists.

My initial Repro:

  • Click the button.
  • Expected: Page scrolls down.
  • Actual: Scroll stutters.
  • Occurs 100% reliably.

If a repro is unstable, we must control variables (e.g., log requests, simulate responses locally). In my case, it was stable.

Problem: Claude couldn’t perceive "stutter" — it “lacks eyes.”

Without a quantifiable measure, the AI essentially has no usable repro. In human teams, similar issues arise when bugs show only under specific environments/configurations.

---

Step 2 — Narrow and Adjust the Repro

Changing a repro carries risk — it may drift away from the actual bug source.

But sometimes it’s unavoidable for collaboration.

> 🎯 Goal: Make the repro simpler, measurable, and scope-specific.

New repro idea for Claude:

  • Record current scroll position.
  • Click the button.
  • Record scroll position again.
  • Expected: Values differ.
  • Actual: Values identical.

Although it doesn’t capture “jitter,” it indicates scroll didn’t happen — possibly related to the same root cause.

Claude implemented logging and simulated clicks with Playwright MCP — confirmed scroll position unchanged.

---

✅ Validate the New Repro

We must ensure this repro can detect a successful fix.

Test:

  • Comment out the network request → Scroll position changes (passes repro).
  • Restore request → Scroll position unchanged (fails repro).

Repeating this consistently showed correlation: network request’s presence directly affected scroll behavior.

---

Step 3 — Eliminate Unrelated Factors

Instructions for Claude:

  • Run the repro → confirm bug exists.
  • Remove something (component, event, style, import).
  • Retest → if bug remains, commit; if fixed, note cause and revert.
  • Repeat until minimal code remains with bug intact.

After iterative removals, Claude reduced the app to a single-file repro — but at one point deviated by testing speculative causes without keeping a bug-present version.

💡 Rule: Always keep a working repro of the bug while narrowing code — like well-founded recursion, each step must shrink scope and still reproduce the bug.

---

Step 4 — Identify the Root Cause

Following strict deletion rules:

  • When removing a file from the routing system, scroll worked fine.
  • Adding back → bug returned.
  • Mounting as top-level route → bug disappeared.

The culprit was:

import { Outlet, ScrollRestoration } from "react-router-dom";

export function RootLayout() {
  return (
    
      
      
    
  );
}

🛠 Root Cause: A known React Router bug (fixed June) where `ScrollRestoration` triggered on every revalidation, not just route changes.

The `action`-triggered network request revalidated the route while scrolling, causing jitter.

---

Debugging Method Recap

  • Reliable repro is non-negotiable.
  • Narrow scope without losing bug presence.
  • Keep deletion strictly incremental.
  • Identify minimal cause → confirm fix.

This method helped me in past large-scale debugging — even stripping half of a React tree down to a 50‑line repro to expose the cause.

---

Specification-driven methods ensure code is anchored to verifiable requirements:

  • Clear specs → what code must do.
  • Linked tests → verify compliance automatically.
  • Iterative updates → specs evolve with product needs.

Benefits:

  • Consistency across teams.
  • Predictability for integration.
  • Confidence in frequent deploys.

---

Vibe Coding with Specs

A progressive coding loop:

  • Draft spec.
  • Minimal implement to meet it.
  • Run spec-linked tests.
  • Iterate based on feedback.

Prevents over-engineering and keeps focus on real goals.

---

Integration with AI Publishing — AiToEarn

Platforms like AiToEarn官网 integrate AI generation, multi-platform publishing, and analytics — enabling developers to:

  • Share debugging techniques or specs on Douyin, Kwai, Bilibili, YouTube, LinkedIn, X(Twitter), etc.
  • Track impact and monetize content.
  • Manage distributed team workflows with connected testing and publishing pipelines.

Links:

AiToEarn博客 · AiToEarn开源地址 · AI模型排名

---

Conclusion

When faced with elusive UI bugs and timing issues:

  • Build a quantifiable repro.
  • Narrow scope systematically, without losing bug visibility.
  • Confirm fixes objectively (not just by “feel”).
  • Use living specifications to guide dev cycles.
  • Share findings using multi-platform AI-aided publishing tools.

This makes your debugging repeatable, collaborative, and documentable — ensuring future issues are easier to track, test, and fix.

Read more