
"Cannot read properties of undefined": JavaScript's most common error, explained
Why 'TypeError: Cannot read properties of undefined (reading ...)' happens, the three most common causes, and how optional chaining and nullish coalescing prevent it.
If you’ve written JavaScript for more than a week, you’ve seen this one:
⛔ Error
TypeError: Cannot read properties of undefined (reading ‘name’)
It’s arguably the single most searched JavaScript error on the internet, and for good reason: it happens constantly, in code that otherwise looks completely fine. Here’s exactly what it means and the handful of shapes it almost always comes in.
What it actually means
The message is literal: your code tried to access a property (.name in the example above) on a value that is undefined. undefined has no properties, so JavaScript throws instead of silently returning something useless.
const user = undefined;
console.log(user.name); // TypeError: Cannot read properties of undefined (reading 'name')
The part in parentheses — (reading 'name') — is the most useful bit of the whole message: it tells you exactly which property access failed, which narrows down where to look even in a long chain like a.b.c.d.
Cause #1: data that hasn’t loaded yet
By far the most common case in real apps: you render a component (or run code) before an async operation has resolved.
function UserCard({ user }) {
// user is undefined on the first render, before the fetch resolves
return <p>{user.name}</p>;
}
const [user, setUser] = useState();
useEffect(() => {
fetchUser().then(setUser);
}, []);
// On the very first render, `user` is still undefined here
The fix is to handle the “not loaded yet” state explicitly, rather than assuming the data is always there:
function UserCard({ user }) {
if (!user) return <p>Loading...</p>;
return <p>{user.name}</p>;
}
Cause #2: destructuring a value that might be null
function getCity({ address }) {
return address.city; // throws if address is null/undefined
}
getCity({ name: "Acme Corp" }); // no `address` key at all
This is especially common with API responses where a field is optional and the backend simply omits it instead of sending null — so response.address is undefined, and .city on it throws.
Cause #3: accessing an element of an empty array
const results = [];
console.log(results[0].id); // results[0] is undefined, not an object
Arrays don’t throw when you index out of bounds — you just get undefined back — but the next property access on that undefined does throw. This one trips people up because the array itself looks completely valid.
The fix: optional chaining and nullish coalescing
Modern JavaScript gives you two operators built specifically for this:
// Optional chaining: short-circuits to undefined instead of throwing
const city = address?.city;
const firstResultId = results[0]?.id;
const deepValue = a?.b?.c?.d;
// Nullish coalescing: supply a default when the value is null/undefined
const name = user?.name ?? "Anonymous";
?. stops evaluating the chain the moment it hits null or undefined and returns undefined instead of throwing. ?? then lets you swap that undefined for a sensible default — note it only triggers on null/undefined, unlike ||, which also triggers on 0, "", and false.
⚠ Optional chaining isn't a substitute for handling the missing-data case
user?.name silently produces undefined instead of crashing, but if your UI then renders that
undefined as literal text or passes it somewhere that expects a string, you’ve just traded a
loud error for a quiet bug. Use ?./?? to prevent the crash, but still design an explicit “no
data yet” state for anything the user will actually see.
“Cannot read properties of undefined” vs “…of null”
You’ll also see the near-identical Cannot read properties of null (reading 'x'). The distinction matters when debugging: undefined usually means a variable was never assigned or a property never existed on the object; null usually means something was deliberately set to “no value” — a DOM query that found nothing (document.querySelector('.missing') returns null), or a database field explicitly nulled out. Both are handled identically by ?./??, but knowing which one you’re looking at often tells you where to start searching.
FAQ
❓ Does TypeScript prevent this error?
With strictNullChecks enabled (part of strict mode), TypeScript flags most of these accesses
at compile time instead of letting them reach the browser as a runtime crash — it’s the single
most effective way to catch this class of bug before shipping.
❓ Is optional chaining slower than a direct property access?
The difference is negligible in virtually every real application — don’t avoid ?. for
performance reasons. Reach for it wherever a value’s presence isn’t guaranteed, and skip it only
where a property is genuinely always defined.
❓ Can I use optional chaining on a function call?
Yes — obj.method?.() calls method only if it exists, and evaluates to undefined instead of
throwing “is not a function” if it doesn’t. Useful for optional callbacks passed as props.
Conclusion
“Cannot read properties of undefined” is almost never a mysterious bug — it’s one of three familiar shapes: data that hasn’t arrived yet, a destructured field that was never sent, or an empty array indexed as if it had content. Optional chaining and nullish coalescing won’t fix the underlying logic gap, but they turn a hard crash into a controllable undefined you can explicitly check for, which is usually exactly what you want while you design the real “no data” state.
References

Co-Founder & CTO at PAPION. Senior full-stack engineer specializing in React, TypeScript, Node.js, and application security.