
Writing code is the easy part. It’s translating a known set of requirements into syntax. Debugging, on the other hand, is the actual job. It is an exercise in applied epistemology: how do you know what you think you know?
When a difficult bug hits, the natural instinct is to start tweaking things. Change a let to a const. Add a console.log. Restart the server. Try it again. This is called "shotgun debugging," and it scales terribly.
Over time, I've had to replace panic with a systematic approach. Here is the mental framework I use when the console is bleeding red and the root cause is nowhere to be found.
The single biggest mistake developers make is changing code before they understand why it's broken.
If you don't know why a bug is happening, any fix you apply is just a coincidence. You might make the symptom disappear, but the underlying rot remains. Instead of guessing, operate like a scientist: form a hypothesis, devise a test to prove or disprove it, and observe the result.
"I think the user object is undefined because the API call hasn't resolved."
Test: console.log(user, isLoading) right before the crash.
Result: Prove it. Only then do you change the code to handle the loading state.
When you're dealing with a large system, the bug could be anywhere. Is it a CSS issue? A React state problem? A bad API payload? A database constraint?
Use binary search. Cut the system in half and figure out which half the bug is in.
Keep halving the search space until you isolate the exact function that is lying to you.
This sounds patronizing, but I have caught myself doing it, and I see junior engineers do it all the time: looking at an error instead of reading it.
Stack traces are intimidating walls of text. Your brain wants to glaze over them and jump back to the code. Resist that urge.
TypeError: Cannot read properties of undefined (reading 'map'))The computer is usually screaming the exact cause of the pain. You just have to listen to its abrasive tone.
Bugs hide in the gap between what you think the code is doing and what it is actually doing. When you are stuck for more than 30 minutes, it is almost always because one of your foundational assumptions is wrong.
useEffect dependency array is missing, so it's running infinitely).When I'm completely blocked, I start physically writing down my assumptions on a piece of paper, and then I use console.log or a debugger to prove each one is true in reality, not just in my head.
Your brain has two modes: focused mode and diffuse mode.
Focused mode is what you use when you're heavily tracking the execution flow of a complex function. It's powerful, but it gets tunnel vision easily.
Diffuse mode is the background processing that happens when you take a shower, make coffee, or walk the dog. It connects disparate ideas.
If you have stared at a bug for 45 minutes and haven't made progress, your focused mode has failed. You are likely stuck in a loop of trying the same three wrong ideas. Get up. Walk away. Let your diffuse mode look at the problem from a different angle. The answer often arrives the moment you stop actively looking for it.
Debugging is not a talent you are born with; it is an algorithm you run in your head.
The next time you face a wall of red text, take a breath. Don't touch the keyboard. Read the error. Form a hypothesis. Cut the search space in half.
The bug is just code doing exactly what you told it to do. You just need to figure out what you actually said.