What to Actually Do With One
You can now read an error's anatomy and name its family. This phase is the part you'll use every day: a calm, repeatable method experienced engineers run almost without thinking. "Stuck for an hour" vs. "fixed in five minutes" is almost never raw skill - it's having a method instead of flailing.
The cheat-card
Match what you're feeling or seeing to the row, then read the section under it.
| The situation | Your first move |
|---|---|
| Wall of red text, panic rising | Find the bottom line (Python) or the type + message line - that's the headline (§1) |
| You read it but it's still gibberish | Translate it into plain English, one piece at a time (§1) |
| You don't know where in your code it is | Find the first line that names a file you wrote (§2) |
| The error only happens "sometimes" | Reproduce it small - shrink it to the minimum that triggers it (§3) |
| You understand it but don't know the fix | Search the exact message (minus your personal bits) (§4) |
| Search results are a sea of unrelated posts | Trim the query to the stable core of the message (§4) |
| You've stared for 20 minutes and you're stuck | Rubber-duck it - explain it out loud, line by line (§5) |
| The error is a long multi-line trace | That's a stack trace - see Reading a Stack Trace |
The rest of this phase is the method behind those moves, in the order you'd run them.
1. Read it literally - the top line first
The error means exactly what it says. Your first job is to read the headline (type + message; the bottom line in a Python traceback, per Phase 1) and translate it into a plain sentence, word by word.
TypeError: Cannot read properties of undefined (reading 'price')
What just happened: Read it literally: "I cannot read the property price, because the thing I tried to
read it from was undefined." That tells the whole story - something you expected to be an object was
empty, and you reached for .price on the emptiness. The error wasn't cryptic; you read it as a blur
instead of a sentence.
💡 Key point. Treat the message as English, not noise. Read each word and ask "what does this word mean here?" Half of all "I have no idea what this means" moments dissolve the instant you read slowly instead of glancing.
2. Find your line
The error often lists several files - many belong to libraries you didn't write. The line that matters most is usually the first one that points at a file you actually created.
Traceback (most recent call last):
File "/usr/lib/python3.11/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.11/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=...)
File "checkout.py", line 12, in <module>
data = json.loads(response)
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
What just happened: The top frames are inside Python's own json library - fine code, don't edit it.
The frame that's yours is checkout.py, line 12, where you called json.loads(response); that's
where your investigation starts. response apparently wasn't valid JSON (it expected a value at the very
first character and found nothing) - the library is just reporting the problem your data caused.
⚠️ Don't start debugging inside library code. Beginners see the topmost file and try to fix code they've never seen. Almost always the bug is at your line, feeding bad input into otherwise-correct code. Scan down for the first file with your project's name. (For long, tangled lists, that's the skill in Reading a Stack Trace.)
3. Reproduce it small
An error you can trigger on demand is one you can fix. One that happens "randomly" is one you don't understand yet. Before fixing, make it happen reliably and as small as possible: comment out unrelated code, replace live data with a hard-coded value that triggers it, shrink a 200-line script to the 5 lines that still break. Each thing you remove that doesn't stop the error is ruled out.
$ python -c "print('Age: ' + 30)"
TypeError: can only concatenate str (not "int") to str
What just happened: Instead of re-running a giant program to study one error, you reproduced the exact
failure in a single line at the terminal (python -c runs the code you pass it). Now you can poke at it
freely - try str(30), see it work - without the noise of everything else. Shrinking a problem to its
broken part is the core move of all debugging.
💡 Key point. "Reproduce it small" does double duty: it confirms you understand what triggers the error, and gives you a fast, isolated place to test your fix. If you can't reproduce it, you can't be sure you've fixed it - only hope.
4. Search the exact message - and read the results
Most errors you'll hit, thousands of people have hit before you. Searching is a real skill, not cheating - how you search decides gold or garbage.
Search the stable, generic part of the message - strip your personal bits. The error names your file, variable, path - unique to you, and it'll wreck the search. Cut them, keep what's the same for everyone.
What you got:
FileNotFoundError: [Errno 2] No such file or directory: 'data/sales_2026.csv'
What to search (strip YOUR specifics):
python FileNotFoundError [Errno 2] No such file or directory
└──── keep the stable core ────┘
✗ don't include 'data/sales_2026.csv' ← that's yours; nobody else has it
What just happened: You kept the language (python) and the universal part, dropping your private file
name. Now you're searching for the category of problem - what other people wrote about, not your one
file, which no page on earth mentions.
How to read a search result - be a skeptic, in this order:
- Match the error first - does the result's text match yours, including the type? A similar-looking message from a different type is a different problem.
- Check it's your language/tool and roughly your version - a fix for an old version, or a different language using the same word, sends you down a rabbit hole.
- Read the accepted/most-upvoted answer and why it works, not just the top code block - an answer you understand teaches you; one you blindly paste breaks again next week.
- Be wary of "just add this flag" with no explanation - if it doesn't say why, you can't tell if it addresses your cause or just silences the symptom.
⚠️ Don't paste fixes you don't understand. The fastest way to turn one bug into three is copying a snippet that "made the error go away" without knowing why. If you can't explain why it works, you haven't fixed it - you've hidden it.
5. When to rubber-duck
If you've read it literally, found your line, reproduced it, and searched - and you're still stuck - you've likely stopped thinking and started staring. The cure is almost silly, and it genuinely works.
📝 Terminology. Rubber-duck debugging is explaining your problem, out loud and in full detail, to an inanimate object (classically a rubber duck on your desk). Narrating every step makes the gap obvious.
Why it works. Explaining your code line by line, out loud, you can't skip the step your brain was silently assuming was fine. Saying "...and then this returns the user, and then I read the name from the user..." you hear yourself and stop: wait - does it actually return the user? What if the lookup found nobody? You located the bug by stating what you'd been taking for granted. A real person works too, but the duck has no ego and is always free.
🪖 War story. Nearly every engineer has walked over to a teammate, started explaining an error from the top, and stopped mid-sentence with "...oh. Never mind. I see it." That's rubber-ducking with a human, and the teammate didn't say a word. Not embarrassing - the method working.
The whole method, in order
1. READ it literally → what does the headline actually say, word by word?
2. FIND your line → first file YOU wrote in the list
3. REPRODUCE it small → shrink to the minimum that still breaks
4. SEARCH the exact message → strip your specifics; read results skeptically
5. RUBBER-DUCK → explain it out loud, line by line, until the gap shows
Run them in order and most errors fall in minutes. Fixing isn't even a separate step - by the time you've truly read, located, reproduced, and understood the error, the fix is usually obvious. The work was never the fix - it was the understanding.
Recap
- Read it literally - the headline means exactly what it says; translate word by word.
- Find your line - the first file you wrote, not library code.
- Reproduce it small - make it happen on demand, with the least code possible.
- Search the exact message - strip personal bits, keep the stable core, read results skeptically, never paste a fix you can't explain.
- Rubber-duck - explain it out loud line by line; the gap reveals itself.
You now have the full "A" of debugging: errors are information, they come in a few recognizable families, and there's a calm method for any of them. Next: the stack trace - the long, multi-line version of an error, same skill scaled up.
Where to go next.
- Reading a Stack Trace - when an error comes with a whole trail of files and line numbers, how to read it to the real cause.
- Reading Logs Without Drowning - when the error is buried in thousands of lines of output, how to find the signal in the noise.
← Phase 2: The Common Error Families · Guide overview
Before the quiz: without looking back, say (or jot down) the core idea of this phase in your own words.
Check your understanding 3 questions
1. What is the first move when facing a wall of red error text?
2. When an error lists several files, which line matters most?
3. Why reproduce an error small before fixing it?