Basic Error Types
When JavaScript breaks, it tells you what went wrong. Learn to read the error name and you'll fix bugs twice as fast.
Errors Have Names
Every error in JavaScript has a name and a message. The name tells you what type of problem it is. The message tells you the details. Always read the name first — it points you straight to the type of fix you need.
// A typical error in the browser console looks like this:
// Uncaught ReferenceError: myVariable is not defined
// ────────────── ───────────────────────
// NAME (type) MESSAGE (details)
Think of error types like a doctor's diagnosis. "Broken bone," "allergy," "infection" — each one tells you immediately where to look and what to do. Same with error names.
SyntaxError — You Wrote Something Wrong
A SyntaxError means JavaScript couldn't even read your code. It's like a sentence with missing words — it just doesn't make sense. Nothing in the file will run when you have a SyntaxError.
// Missing closing bracket
console.log("hello";
// ❌ SyntaxError: Unexpected token ';'
// Missing closing brace
if (x === 1) {
// ❌ SyntaxError: Unexpected end of input
- Caused by: missing brackets, typos, unclosed quotes, wrong punctuation
- When: before your code even starts running
- Fix: look at the line number in the error and check your brackets and quotes
ReferenceError — You Used Something That Doesn't Exist
A ReferenceError means you tried to use a variable that JavaScript has never heard of. Maybe you spelled it wrong, or forgot to create it first.
console.log(myVar);
// ❌ ReferenceError: myVar is not defined
// Accessing a variable before declaring it
console.log(count);
let count = 0;
// ❌ ReferenceError: Cannot access 'count' before initialization
- Caused by: typos in variable names, using a variable before declaring it, wrong scope
- When: while the code is running, when it hits that specific line
- Fix: check your spelling, check you declared the variable, check it's in scope
TypeError — You Used the Wrong Type of Thing
A TypeError means the variable exists, but you're
trying to do something it can't do. Like trying to call a number as
a function, or reading a property from null.
const name = null;
console.log(name.length);
// ❌ TypeError: Cannot read properties of null
const num = 42;
num();
// ❌ TypeError: num is not a function
const obj = {};
obj.doSomething();
// ❌ TypeError: obj.doSomething is not a function
-
Caused by: calling something that isn't a function, reading a
property from
nullorundefined, reassigning aconst - When: while the code is running
- Fix: check the variable actually has a value and is the right type before using it
Quick Summary Table
| Error | Simple meaning | When it happens |
|---|---|---|
SyntaxError |
Your code has a typo or missing bracket | Before anything runs |
ReferenceError |
You used a variable that doesn't exist | While running |
TypeError |
You used the right name but the wrong type | While running |
Other Errors You Might See
| Error | When you see it |
|---|---|
RangeError |
A number is outside its allowed range — e.g.
new Array(-1)
|
URIError |
Bad URL passed to decodeURIComponent() |
AggregateError |
Multiple errors at once — seen with Promise.any()
|
Error Properties
try {
null.toString();
} catch (e) {
e.name; // "TypeError"
e.message; // "Cannot read properties of null (reading 'toString')"
e.stack; // full stack trace as a string (non-standard but universal)
}
How to Read an Error in the Console
// TypeError: Cannot read properties of undefined (reading 'name')
// at getUserName (app.js:14) ← the function where it broke
// at main (app.js:27) ← the function that called it
//
// Read from the bottom up. main (line 27) called getUserName (line 14).
// The real problem is on line 14 inside getUserName.
The list of lines under an error is called a stack trace. Read it from the bottom up to trace back to where the problem started.
Throwing Your Own Errors
function divide(a, b) {
if (b === 0) {
throw new RangeError("Cannot divide by zero");
}
return a / b;
}
You can create your own errors using
throw new ErrorType("message"). Pick the right type —
it makes your error easier to understand and catch.
Custom Error Classes
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
throw new ValidationError("Required", "email");
// ValidationError: Required
// e instanceof ValidationError → true
// e instanceof Error → true (inheritance)
Extending Error gives you proper
instanceof checks, the full stack trace, and lets
callers distinguish your custom errors from generic ones in
catch blocks.
Real-World Examples
// SYNTAX ERROR — your code has a typo, nothing runs at all
// conts userName = "Maya"; ← typo: "conts" instead of "const"
// SyntaxError: Unexpected identifier 'userName'
// REFERENCE ERROR — using a variable that doesn't exist
// Happens a lot when you misspell a variable name
try {
console.log(useerName); // typo — should be "userName"
} catch(e) {
console.log("ReferenceError caught:", e.message);
}
// TYPE ERROR — the most common one: reading from null/undefined
// Happens when an API returns null and you try to use its properties
const userData = null; // API returned nothing
try {
console.log(userData.name); // ❌ can't read .name from null
} catch(e) {
console.log("TypeError caught:", e.message);
}
// THE FIX — always check before using
const safeName = userData?.name ?? "Guest";
console.log("Safe name:", safeName);
Try It: Code Runner
Trigger different errors and catch them safely with
try...catch. Read the error messages carefully!
Common Mistakes
-
Mixing up ReferenceError (variable doesn't exist) and TypeError
(variable exists but is
nullor wrong type). - Skipping the line number in the error — it tells you exactly where to look.
- Only reading the message and ignoring the type — the type alone usually tells you the fix.
Best Practices
- Read the type first, then the message, then the stack trace (bottom to top).
-
When throwing manually, use the most accurate type — not always
just
Error.
Interview Questions
Difference between SyntaxError and ReferenceError?
SyntaxError means the code is broken before it even runs. ReferenceError happens while running when you try to use a variable that doesn't exist.
When do you get a TypeError?
When you try to use a value in a way it doesn't support — like calling a number as a function, or reading a property from null.
✏️ Exercise
Guess the error type before running each one: (1)
conts x = 1, (2) console.log(z), (3)
null.toString(), (4) new Array(-5). Then
run them and check.
🧠 Quiz
1. Which error stops the whole script before a single line runs?
SyntaxError — it happens during parsing, before execution starts.
2. What does the stack trace tell you?
The chain of function calls that led to the error, and the exact file and line where each one happened.
🚀 Mini Challenge
Write a function safeDivide(a, b). Throw a
TypeError if either argument is not a number. Throw a
RangeError if b is zero. Wrap calls in
try...catch and log the error name and message.
Summary
- SyntaxError — broken code, nothing runs at all.
- ReferenceError — variable doesn't exist or out of scope.
- TypeError — variable exists but you're using it the wrong way.
- Always read: type → message → stack trace (bottom to top).
Related Topics
MDN reference: developer.mozilla.org → JavaScript → Error