learn.colinkim.dev

Reading stack traces

Learn how to read error messages and stack traces to quickly find the source of a problem instead of guessing what went wrong.

When JavaScript encounters an error it cannot handle, it prints an error message and a stack trace. The stack trace tells you exactly where the problem is. Learning to read them turns a frustrating debug session into a thirty-second fix.

Anatomy of an error

TypeError: Cannot read properties of undefined (reading 'name')
    at displayUser (app.js:15:23)
    at loadData (app.js:8:5)
    at HTMLButtonElement.<anonymous> (app.js:3:1)

This message has three parts:

  1. Error typeTypeError — what kind of error occurred
  2. MessageCannot read properties of undefined (reading 'name') — what went wrong
  3. Stack trace — the list of function calls that led to the error

Error types

The most common error types:

| Type | What it means | |---|---| | TypeError | A value is not the expected type — calling a method on undefined, passing wrong arguments | | ReferenceError | A variable is not declared — typo in a variable name, accessing a variable out of scope | | SyntaxError | The code has invalid syntax — missing bracket, unmatched parenthesis | | RangeError | A value is outside the valid range — infinite recursion, invalid array length | | Error | A generic error — usually thrown manually with new Error("...") |

Reading the stack trace

Each line in the stack trace is one function call, listed from most recent to oldest:

    at displayUser (app.js:15:23)    ← where the error happened
    at loadData (app.js:8:5)          ← who called displayUser
    at HTMLButtonElement.<anonymous> (app.js:3:1)  ← the original trigger

The format is:

at functionName (filePath:lineNumber:columnNumber)

The first line is where the error occurred. The lines below show the call chain — how the code got there.

Finding the problem

Start with the first line:

at displayUser (app.js:15:23)

Go to app.js, line 15, column 23. That is the exact position where the error happened.

The message says Cannot read properties of undefined (reading 'name'). So something on line 15 is trying to read .name on undefined:

// app.js line 15
console.log(user.name);  // user is undefined

Then trace backward through the stack to find where user should have been set:

at loadData (app.js:8:5)

Line 8 of app.js called displayUser with the bad value.

Common error messages

Cannot read properties of undefined (reading 'x')

You are accessing a property on undefined. Check the value before the dot:

user.name;  // user is undefined

Fix by checking for existence or providing a default:

user?.name;        // undefined — no error
user && user.name; // undefined — no error

x is not a function

You are trying to call something that is not a function:

const value = "hello";
value.push("!");  // "hello".push is not a function — strings do not have .push()

Cannot set properties of null (setting 'x')

You are trying to set a property on null. Usually happens when a DOM element is not found:

const modal = document.querySelector(".nonexistent");
modal.textContent = "Hello";  // modal is null

Unexpected token

A syntax error — the parser found invalid syntax:

const obj = { name: "Ada", };  // trailing comma in object literal — valid in modern JS
const obj = { name: "Ada" }    // missing semicolon if next line starts with (

Maximum call stack size exceeded

Infinite recursion — a function calls itself without a base case:

function factorial(n) {
  return n * factorial(n - 1);  // no base case — runs until stack overflows
}

Stack traces in async code

Async stack traces include promise and async function frames:

Error: Failed to fetch
    at apiRequest (api.js:12:11)
    at async loadData (app.js:5:18)
    at async HTMLButtonElement.<anonymous> (app.js:2:3)

The async keyword before function names in the stack trace indicates the error occurred inside an async function.

Minified code

In production builds, code is often minified — variable names shortened, whitespace removed, everything in one file. Stack traces in minified code point to positions in the minified file, not your source code:

at n (app.a3f2b.js:1:4823)

Source maps translate these back to your original source. They are generated by build tools and should not be deployed to production for security reasons, but are essential for local debugging.

What to carry forward

  • error messages have a type, a description, and a stack trace
  • the stack trace lists function calls from most recent to oldest
  • the first line is where the error happened; subsequent lines show how the code got there
  • go to the file, line number, and column to find the exact problem
  • common errors like undefined property access and not a function are quick to fix once you recognize them
  • minified stack traces require source maps to be readable

Stack traces are your first tool when something goes wrong. The next lesson covers the other tools — console and browser DevTools.

Progress

Quick checks

No quick checks in this lesson.

Mark lesson manually or answer quick checks to track progress.