The Simple Method I Use to Debug Anything

I have a 5-step method that never fails: read the error - persist the environment - divide the problem - explain to a rubber duck - git bisect. Sounds silly, but this is what lets me sleep at 2 AM.

· · 4 min read

Last week I was on a deadline. Feature needs to ship tomorrow morning. But staging is broken and nobody knows why.

The team panicked. I panicked too - but I have a method that never fails.

This isn't some fancy AI technique. Not a new tool. It's 5 simple steps I use for every bug - and no matter how complex the problem, this method always finds the answer.

---

Step 1: Actually Read the Error

Sounds stupid. But 90% of bugs are solved at this step.

What I mean: read the error from start to finish. Including the stack trace. Including line numbers. Including file paths.

Most developers see "TypeError: undefined is not a function" and immediately open Google. But 5 seconds later in the stack trace there's "*at Component.render (src/pages/Checkout.jsx:143)*" which tells you exactly which file and line is broken.

I always ask: "What actually happened? What line? What data was involved?"

Real example: My team once panicked for 2 hours over a 500 API error. After actually reading the log, it was just a missing trailing slash in the URL. 5 second fix.

---

Step 2: Persist the Error Environment

This is critical: before you touch anything, record the environment where the error occurs.

• What browser? What version?
• What OS?
• What input did you provide?
• What was the application state?

Why? Because you're going to experiment and might accidentally change the state. If you forget the initial conditions, you can't reproduce.

I once debugged a bug that only appeared in Firefox Android version 120 - Chrome and Firefox desktop were fine. If I hadn't noted "Firefox Android 120" from the start, I'd be stuck in a loop between "can't reproduce" and "panic."

Reproduce > Fix. If you can't reproduce it, you can't verify the fix.

---

Step 3: Divide and Conquer - Binary Search Your Code

This is the most powerful technique: split the problem in half, determine which half is broken.

If your app has 10 steps (A → J), and output at J is wrong:
• Check output at E. If correct, the problem is in F → J.
• Check output at H. If wrong, the problem is in F → H.
• Repeat.

Log(n), not n. Complexity drops dramatically.

This is binary search for debugging. Keep halving until you find the broken piece.

Example: API returns wrong data. You split:
1. Is the database returning correct data? (Check raw query)
2. If yes: problem is in the transformation or response layer
3. Check the transformation: console.log each step
4. Found it: your mapping function mishandles null

---

Step 4: Explain It to a Rubber Duck

This is legendary in software engineering. Because it actually works.

Here's how: explain the bug to an inanimate object (rubber duck, monitor, water bottle) out loud.

When you explain, your brain is forced to restructure the problem. And 80% of the time, mid-explanation you'll suddenly know the answer.

I use this every week. Just yesterday: "So duck, the problem is user data doesn't show after login. First, the frontend sends a token to /api/me. Then the backend... oh. I forgot to include the auth middleware on that route."

5 seconds. Thanks, rubber duck.

---

Step 5: Git Bisect - Let the Computer Find It

If a bug appeared in production and you know "this used to work." Don't manually checkout commits one by one.

git bisect start
git bisect bad # current commit is broken
git bisect good v1.0.0 # last known working version

Git will checkout a commit in the middle. You test. You say git bisect good or git bisect bad. Git binary searches until it finds the first commit that introduced the bug.

I cut debugging from hours to 10 minutes with git bisect.

---

Why This Method Works

Because debugging isn't about being a genius - it's about having a process.

Every bug, no matter how complex, can be chased down with:
1. Read the actual error → get context
2. Record the environment → reproduce reliably
3. Binary search → cut the problem space
4. Rubber duck → restructure your thinking
5. Git bisect → let the tools find it

I don't use AI for debugging. I don't use expensive tools. Just these 5 steps.

*Next week when you get a weird bug in production: don't panic. Start with step 1 - read the error from start to finish. 90% of the time you won't even reach step 5. If you're stuck, there's a rubber duck on your desk waiting.*