Skip to content
Happy Programming Guide
Start learning
JavaScript

What “Cannot read properties of undefined” Means and How to Fix It

The most common JavaScript error, decoded: you asked for a property of something that does not exist yet. How to read the message, find which value is undefined, and the fixes.

A person working on a laptop

TypeError: Cannot read properties of undefined (reading 'name') means your code did something.name and something was undefined. The message tells you the property you tried to read, but not the variable that was undefined — and finding that variable is the whole job. The value is missing for one of a few reasons: it has not arrived yet, the path to it is wrong, or the thing you expected to exist does not.

Reading the message#

JavaScript
const user = undefined;
console.log(user.name);
// TypeError: Cannot read properties of undefined (reading 'name')

“Reading ‘name'” is the property. “Of undefined” is the object it was read from. The message never names the variable, because by the time the error happens the engine only has the value, not the name. Older browsers phrase it as Cannot read property 'name' of undefined; same error.

The same message with null instead of undefined has the same causes; null usually means something was set to nothing on purpose, undefined means it was never set.

Finding the undefined value#

Take the line number from the error, look at the expression, and log each step of the chain:

JavaScript
// Line from the stack trace:
const city = response.data.user.address.city;

// Which link is missing? Log the chain one level at a time
console.log(response);
console.log(response.data);
console.log(response.data.user);
console.log(response.data.user.address);   // this one prints undefined

The first console.log that prints undefined is the culprit: address is missing, so reading .city from it throws. Now you know what is missing; the sections below cover why.

Cause 1: it has not arrived yet#

JavaScript
let user;
fetch('/api/user').then(r => r.json()).then(data => { user = data; });
console.log(user.name);        // runs before the fetch finishes: user is undefined

Anything that involves the network, a timer, or reading a file completes later. Code that uses the result must run after it arrives, which means inside the callback, after an await, or in an effect that reacts to the value changing:

JavaScript
const response = await fetch('/api/user');
const user = await response.json();
console.log(user.name);        // now it exists

Cause 2: the path is wrong#

The data is there but not shaped the way the code assumes. An API returns { user: { ... } } and the code reads data.profile. Or it returns an array and the code treats it as an object. The log-the-chain technique above shows the real shape; adjust the path to match.

JavaScript
console.log(JSON.stringify(data, null, 2));   // see the actual structure

Cause 3: the element does not exist#

JavaScript
const button = document.getElementById('submit-btn');
button.addEventListener('click', handler);
// Cannot read properties of null (reading 'addEventListener')

Either the id is misspelt, or the script ran before the HTML was parsed. Check the id in the HTML, and load the script with defer or place it at the end of the body so the elements exist first.

Cause 4: wrong scope or this#

JavaScript
class Counter {
  count = 0;
  increment() { this.count++; }
}
const c = new Counter();
button.addEventListener('click', c.increment);
// Cannot read properties of undefined (reading 'count') - this is undefined

Passing a method as a callback loses its this. Use an arrow function, () => c.increment(), or bind it. Array destructuring and function parameters produce the same error when a caller passes fewer arguments than expected.

Optional chaining#

?. stops the chain and returns undefined instead of throwing:

JavaScript
const city = response?.data?.user?.address?.city;   // undefined, no error
const label = city ?? 'Unknown';                       // default if missing

Use it when the value is legitimately optional: a user who may not have an address. Do not use it to silence an error you have not understood. If data should always exist, data?.user hides a real bug and moves the failure somewhere harder to find.

The React version#

JSX
function Profile() {
  const [user, setUser] = useState();            // undefined on first render
  useEffect(() => { fetchUser().then(setUser); }, []);
  return <h1>{user.name}</h1>;                     // crashes on the first render
}

The component renders before the data arrives. Either give state a sensible initial value, or render a loading state until it exists:

JSX
const [user, setUser] = useState(null);
if (!user) return <p>Loading…</p>;
return <h1>{user.name}</h1>;

This one bug accounts for a large share of all React crashes on first load.

Defensive habits#

  • Initialise state and variables with the shape you expect: [] for lists, null for a not-yet-loaded object, never leave them undefined by accident.
  • Validate API responses at the boundary, once, rather than guarding every access.
  • Use TypeScript; it turns most of these into compile-time errors with the variable named.

Questions people ask#

What is the difference between undefined and null here?

Nothing, for this error: reading a property of either throws. Semantically, undefined means never assigned; null means deliberately empty.

Why does the message not say which variable?

By the time the property read fails, the engine has only the value. Source maps and a good debugger show the expression; a console.log chain shows the link.

Can this happen with arrays?

Yes: items[5].name when the array has three elements, or items.find(...) returning undefined because nothing matched. Check the length and the find result.

Does try/catch fix it?

It stops the crash. It does not make the value appear. Use it only where a missing value is genuinely acceptable and you handle that case.

Where to go next#

Fixing 'x is not a function' in JavaScriptRead next

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *