# 13.8 When it breaks: reading an error (/building-ai-workers/programming-fundamentals/reading-an-error)

---
type: Document
title: "13.8 When it breaks: reading an error"
description: "How to read a Python traceback and a Node stack trace, find the first line in your own code, and name the cause in one sentence."
status: stable
order: 313.08
ksor:
  owner: team:panaversity
  audience: [ public ]
  approval:
    by: process:panaversity
    at: 2026-11-09T19:52:57Z
chapter: "13"
part: III
expert_status: builder-only
concepts: [ "13.8" ]
last_verified: 2026-10-30
generated:
  at: 2026-11-09T19:52:57Z
  by: process:panaversity
trust_tier: unverified
build_id: sha256:46fd53c5d7ab1c14f6347908d45c9fdaecda4d914439923ee878bdcecd57803e
dirty: true
ksor_version: 0.0.60
---

**In everyday life.** When a car's dashboard light comes on, "the car is broken" does not help the mechanic. "The oil light came on at highway speed, and the engine was hot" does.

**What you will learn.** How to read what a program prints when it fails, and name the cause in one sentence.

**Why it matters.** When a program breaks, it tells you what went wrong and where. Read it, and tell the agent exactly what broke.

When a program fails, it prints an **error report**: a **stack trace** in TypeScript under Node, a **traceback** in Python. Both say what kind of error it was, its message, and the chain of function calls that led to the line. A function calls another when it uses it.

### Where do I start reading an error?

At the bottom for Python, and at the top for Node. Python tells it like a story, with the ending last: the oldest call comes first, and the failing line and then the message come last. Node tells it like a news report, with the headline first: the message near the top, then the failing line, then the lines that called it.

In both, skip the lines that point into the language itself, such as `node:internal` and `<frozen runpy>`. Then, starting from the message, find the first line in a file you own.

### Why is the failing line not always the bug?

A program **raises** an error, stopping to report it, at the line where a bad value finally causes trouble. The bug is often earlier, where the bad value came from. It is like a payment the bank sends back: the mistake was made earlier, when someone typed the vendor's account number. Follow the chain back to the first place in your own code that passed it along.

**At work.** Ana has the agent run the reconciliation script, which checks each stated due date against the terms, on a file with no `terms` column. Both languages fail.

Predict: which line in your own code did the bad value come from?

```text tab="TypeScript" tab-group="language"
$ npm run reconcile -- data/invoices-no-terms.csv
file:///.../src/due-date.ts:13
    throw new Error(`Unknown terms: ${terms}`);
          ^

Error: Unknown terms: undefined
    at termsDays (file:///.../src/due-date.ts:13:11)
    at dueDate (file:///.../src/due-date.ts:22:39)
    at reconcile (file:///.../src/reconcile.ts:16:22)
    at file:///.../src/reconcile.ts:26:17
    at ModuleJob.run (node:internal/modules/esm/module_job:439:25)
```

```text tab="Python" tab-group="language"
$ uv run python -m brightline_ap.reconcile ../data/invoices-no-terms.csv
Traceback (most recent call last):
  File "<frozen runpy>", line 88, in _run_code
  File ".../py/brightline_ap/reconcile.py", line 31, in <module>
    found = reconcile(Path(file).read_text(encoding="utf-8"))
  File ".../py/brightline_ap/reconcile.py", line 21, in reconcile
    computed = due_date(row["invoice_date"], row["terms"])
                                             ~~~^^^^^^^^^
KeyError: 'terms'
```

In the Node report, the first lines are in `due-date.ts`, which raised the error on purpose, with `throw`. The bug is one step further down, at `reconcile.ts:16`, which passed `undefined`. In the Python report, the message is at the bottom, and just above it Python marks the exact expression, `row["terms"]`.

**Ana's sentence.** "The error is raised in `due-date.ts`, but the cause is `reconcile.ts` line 16: this file has no terms column, so the terms it passes are undefined." In Python, her sentence would name `reconcile.py` line 21, which asks for a column the file does not have. Then she asks: "Please make the script stop with a clear message that names the missing column. Don't fill in default terms."

**"It broke" is not enough.** The most expensive habit is saying "it failed, fix it" without reading the error. Like a mechanic asked only to turn the oil light off, the agent may hide the error instead of fixing its cause, for example by giving every row with no terms "Net 30".

**Where the languages differ.** A missing key in TypeScript gives `undefined`, which is passed along until something else fails, so the error appears far from the cause. Python raises `KeyError` at the lookup itself.

### Try it

The file in `13-8` is the `while` loop from [13.4](decisions-and-repetition.md#how-does-a-loop-stop). It works. You are going to break it.

**Modify.** Send: "Please remove the empty page, the last `[]`, from the list of pages in the file. Don't run it yet." Predict what happens now.

**Run.** Send: "Please run the file and show me the whole error. Don't explain it yet."

**Investigate.** Read the report from where this lesson says to start. Write one sentence that names the file, the line and the cause. Then ask the agent what it thinks, and compare.

**Make.** Send: "Please change the loop so it also stops at the end of the list, even with no empty page. Run it."

**What you should see.** Two pages print, then a `TypeError` in TypeScript or an `IndexError` in Python, on the `while` line. The cause is the data you changed. After the fix, it stops at page 3 with no error.

**The operating rule:** read the error before you ask for a fix, find the first line in your own code, follow the bad value back, and name the file, the line and the cause in one sentence.

![Figure 13.9. Two error reports with the lines that matter marked. In the Node report, read the message at the top, find where the error was raised in due-date.ts, and trace the bad value back from reconcile.ts line 16. In the Python report, read the KeyError on the last line first, then look upward to the failing line.](img/error-report.png)

*Figure 13.9. Reading an error report. In Python start at the bottom, in Node start at the top, and in both find the first line in a file you own, then follow the bad value back.*

**Next.** An error tells you what went wrong. [13.9](tests-first.md) writes down what right looks like, before any code exists.
