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.
0xNN · · 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.*