top of page

Reading Error Messages Like a Developer

  • Shawn West
  • Nov 25, 2025
  • 6 min read

Updated: Aug 10

A 40-line stack trace scrolls up your screen and your brain says something is very wrong. The instinct is to grab the whole thing, drop it into a search bar, and hope a stranger has seen it before.

Here's the calmer truth: most error messages already tell you what went wrong and where. The skill isn't memorizing errors. It's reading the answer the computer just handed you — the same way a mechanic reads the dashboard light instead of photographing it to send to a friend.

This is a foundational skill, and it's very learnable. Let's build it slowly.

The answer the computer already gave you

Every error, in almost every language, carries three pieces of information. Once you can spot them, the wall of text turns into a short sentence.

  • What — the type of error (TypeError, AttributeError, and so on)

  • Why — a plain-English description of what went wrong

  • Where — the file and line number it happened on

Look at this JavaScript error:

TypeError: Cannot read properties of undefined (reading 'email')
    at getUser (/app/src/users.js:15:22)

Now read it as What / Why / Where:

  • What: a TypeError — you used a value in a way its type doesn't allow.

  • Why: you tried to read .email on something that was undefined — a box you expected to be full was empty.

  • Where: users.js, line 15.

Three pieces. That's everything you need to start. You haven't fixed anything yet, but you already know the file to open and the exact thing that was missing.

Do this: before you search for anything, split the error into What, Why, and Where. Say each part out loud in plain words. You'll often find you no longer need to search at all.

Reading a stack trace without flinching

A stack trace (Python calls it a traceback) is just a list of the steps the program took to reach the error — like a trail of breadcrumbs. It reads a little differently than you'd expect: in Python, the actual error is at the bottom, and the steps above it show how the program got there.

Traceback (most recent call last):
  File "app.py", line 42, in <module>
    total = calculate_total(cart)
  File "pricing.py", line 18, in calculate_total
    return sum(item.price for item in items)
AttributeError: 'NoneType' object has no attribute 'price'

Read it from the bottom up:

  1. The bottom line is the What and the Why: AttributeError: 'NoneType' object has no attribute 'price'. Something was None (empty), and you asked it for .price, which empty things don't have.

  2. The line just above it is the Where: pricing.py, line 18.

  3. The lines above that are the trail — app.py line 42 called calculate_total, which is where the trouble started.

One more habit, and it's the big one: find your file, not the library's. Long traces often include frames from code you didn't write — deep in Python itself, or inside a package you installed. Those are rarely where you fix things. Scan the trace for the file with your name on it — here, pricing.py and app.py. That's your line. That's where you look first.

Do this: read the trace bottom to top, note the last line (What + Why), then find the topmost frame that lives in your code. Open that file at that line.

One bug, all the way to the fix

(Developed example — a simple scenario.)

Let's walk the trace above from panic to a one-line fix, doing the whole read-don't-google loop once.

You're building a tiny shopping-cart app. You run it, and you get exactly the traceback above. Here's the loop, slowly:

See the error. A red block appears. Take a breath — it's an answer, not a scolding.

Read the What and Why. Bottom line: AttributeError: 'NoneType' object has no attribute 'price'. Translation: somewhere, a thing you thought was a product turned out to be None — nothing — and you asked that nothing for its .price.

Read the Where. The frame above it points at pricing.py, line 18.

Open that exact line. You go to pricing.py, line 18, and see:

def calculate_total(items):
    return sum(item.price for item in items)   # line 18

This line walks through every item in the cart and adds up item.price. The error says one of those items is None. So the cart isn't a clean list of products — a blank slipped in. Maybe a lookup missed and returned None, and that None got added to the cart anyway.

Spot the cause. You print the cart to check:

print(cart)
# [Product('Book', 12.0), None, Product('Pen', 3.0)]

There it is — a None sitting between two real products. The list has a hole in it.

The one-line fix. Skip the empty slot when you add things up:

return sum(item.price for item in items if item is not None)

Run it again. Green. Total prints correctly.

Notice what you didn't do: you never searched the web, never copied the whole trace anywhere. The computer told you the type (AttributeError), the reason (a None where a product should be), and the address (pricing.py, line 18). You just read the answer and followed it home. (The deeper question — why did a None get into the cart in the first place? — is worth chasing too, and it's the kind of thing a good test would catch before your users do. More on that in Testing the Hard Parts.)

Do this: next time you hit an error, run this exact loop — see it, read What/Why/Where, open that line, print the suspicious value, make the smallest fix. One pass, no search bar.

A few error types you'll meet early

Most errors you see in your first months are a handful of familiar faces. Here's a plain-language reference — the What, what it usually means, and the first thing to check.

Error type

Plain meaning

First thing to check

TypeError

You used a value in a way its type doesn't allow (added text to a number, called something that isn't a function).

What is the value actually? Print it. It's often None/undefined.

AttributeError / undefined is not ...

You asked for a property or method the value doesn't have.

Is the thing empty (None/undefined), or did you misspell the name?

NameError / ReferenceError

You used a name the program has never heard of.

A typo, or a variable used before it was created (or out of scope).

IndexError / KeyError

You reached for a list position or dictionary key that isn't there.

Is the list shorter than you think? Does that key really exist?

SyntaxError

The code is written in a way the language can't parse.

Look just before the pointed-at spot — a missing ), :, or quote.

You don't need to memorize this. You need to recognize that the error has a name, and the name narrows the search to one small question.

Do this: when an error appears, name its type first, then jump straight to the "first thing to check" — that one question solves most beginner bugs.

When to actually search

Reading the error yourself isn't a rule against ever searching — it's about searching well, and only after you understand what you're searching for.

Search when the Why doesn't make sense in plain English, when the error comes from deep inside a library and nothing in your own files looks wrong, or when the message uses words you genuinely don't know. When you do search, paste the error type and the short Why (for example, AttributeError 'NoneType' object has no attribute), not the whole 40-line trace with your file paths in it. A tight search finds a real answer; a giant paste finds noise.

And remember that "the computer is answering, not attacking" applies to more than code. The same calm reading turns a scary test report into a to-do list, and helps you tell a real bug from a low-priority one instead of treating every red line as a five-alarm fire.

Do this: try to read the error yourself first. If you still search, search for the type + short Why, never the whole trace.

Sources

  • Error message text and stack-trace formats are drawn from standard Python (CPython) and JavaScript (V8/Node.js) runtime output.

  • The shopping-cart bug is a developed composite example — a simple, realistic scenario written to teach the read-the-error loop, not a report of a specific incident.

Keep learning. This article is part of the Start Here path in the ShiftQuality Learning Center. New to testing? A good next step is Your First Week as a Software Tester.

bottom of page