Most beginners see a red error in the console and immediately feel lost. That's completely normal, but error messages are actually your best friend. They are the program telling you, in plain terms, exactly what broke and where. Once you learn to read them, debugging becomes far less scary.
Anatomy of an error message
Every JavaScript error follows the same structure. Here is a real example:
Uncaught TypeError: Cannot read properties of undefined (reading 'name')
at getUserName (app.js:15:25)
at handleClick (app.js:42:10)
at HTMLButtonElement.<anonymous> (app.js:50:5)The message has three distinct pieces:
- Error type:
TypeErrortells you the category of problem. There are about six common types you'll see regularly. - Error description:
Cannot read properties of undefined (reading 'name')explains what went wrong in plain language. - Stack traceWhat is stack trace?A list of function calls recorded at the moment an error occurs, showing exactly which functions were active and in what order.: the indented lines starting with
atshow you the chain of function calls that led to the crash.
Read the error type and description first. They already tell you most of what you need to know before you even look at the stack trace.
Understanding the stack traceWhat is stack trace?A list of function calls recorded at the moment an error occurs, showing exactly which functions were active and in what order.
The stack trace lists function calls from most recent (top) to oldest (bottom). Think of it like a call history on your phone: the top entry is the last thing that happened before the crash.
at getUserName (app.js:15:25) ← Error occurred here
at handleClick (app.js:42:10) ← Which was called from here
at HTMLButtonElement (app.js:50:5) ← Which was triggered by thisThe format app.js:15:25 means: file app.js, line 15, column 25. In a browser, you can click that link directly to jump to the relevant line in your DevTools source panel.
Working through a real example
Here is the code that produced the error above:
function getUserName(user) {
return user.name.toUpperCase(); // line 15
}
function handleClick() {
const name = getUserName(currentUser); // line 42
console.log(name);
}
button.addEventListener('click', handleClick); // line 50The error says: at line 15, we tried to read .name from user, but user was undefined. That means currentUser was undefined when handleClick was called. Fixing it is straightforward once you understand the cause:
function getUserName(user) {
if (!user) return 'Guest';
return user.name.toUpperCase();
}Now if currentUser is ever undefined, the function returns a safe fallback instead of crashing.
Where errors appear
Errors show up in slightly different places depending on your environment.
Browser DevTools
Open the console with F12 (or Cmd+Option+J on Mac). Errors appear in red. Warnings appear in yellow. You can click the filename and line number in the stack traceWhat is stack trace?A list of function calls recorded at the moment an error occurs, showing exactly which functions were active and in what order. to jump straight to the problematic code in the Sources tab.
Uncaught TypeError: Cannot read properties of undefined (reading 'name')
at app.js:15Node.js terminalWhat is terminal?A text-based interface where you type commands to interact with your computer. Also called the command line or shell.
Errors print to your terminal. Node.js shows full file paths and exits the process if the error is uncaught.
TypeError: Cannot read properties of undefined (reading 'name')
at getUserName (/home/user/app.js:15:25)
at Object.<anonymous> (/home/user/app.js:42:10)The structure is identical, you read it the same way. The main difference is that Node.js shows absolute paths rather than just filenames.
Common patterns to recognize
Once you have seen a few error messages, you start recognizing patterns. These three come up constantly:
"Cannot read properties of undefined"
// Problem: accessing a property on something that doesn't exist yet
const userName = user.name; // user is undefined
// Fix: use optional chaining
const userName = user?.name; // returns undefined instead of crashing"X is not a function"
// Problem: calling .map() on something that isn't an array
const result = data.map(x => x.id); // data might be null or an object
// Fix: check the type first
if (Array.isArray(data)) {
const result = data.map(x => x.id);
}"Unexpected tokenWhat is token?The smallest unit of text an LLM processes - roughly three-quarters of a word. API pricing is based on how many tokens you use."
// Problem: missing closing brace
function greet() {
console.log('hello');
// SyntaxError: Unexpected end of input
// Fix: close all your braces
function greet() {
console.log('hello');
}Quick reference
| Part of the error | What it tells you | What to do |
|---|---|---|
Error type (TypeError) | Category of problem | Look up what that type means |
| Error description | What specifically went wrong | Read it carefully, it's usually direct |
| Stack trace (top line) | File and line of the crash | Go to that line first |
| Stack trace (other lines) | What called the broken code | Trace back if the top line isn't obvious |
When you are stuck, copy the error type and description and paste it into a search engine. You are almost never the first person to encounter any given error message, the fix is usually already documented somewhere.