Real-world examples of TypeError in JavaScript (and how to fix them)

If you write JavaScript long enough, you will hit a TypeError. Probably today. The best way to get comfortable with them is to walk through real examples of TypeError in JavaScript, see why they happen, and learn how to debug them quickly. In this guide, we’ll look at practical examples of TypeError in JavaScript that mirror what developers run into on Stack Overflow and in production apps. Instead of abstract theory, we’ll focus on real examples: calling functions on `undefined`, misusing `this`, mixing up primitives and objects, and more. These examples include modern JavaScript patterns from 2024–2025: async/await, optional chaining, and front-end frameworks. By the end, you’ll recognize a TypeError stack trace at a glance and know exactly where to start looking. Think of this as your field guide to the best examples and the most common mistakes that trigger TypeError in everyday JavaScript development.
Written by
Jamie
Published

The most common examples of TypeError in JavaScript

Let’s start with the errors you’re most likely to see in the wild. These real examples of TypeError in JavaScript are taken straight from patterns that show up repeatedly on Stack Overflow and GitHub issues.

The classic pattern looks like this:

TypeError: Cannot read properties of undefined (reading 'foo')
// or in older engines:
TypeError: Cannot read property 'foo' of undefined

That message tells you almost everything you need to know: you tried to use a property or method on something that isn’t the type you thought it was.


Example of Cannot read properties of undefined

One of the best examples of TypeError in JavaScript is the very first bug most beginners hit:

const user = getUser(); // sometimes returns undefined

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

Why it happens:

  • getUser() can return undefined (for example, if the user is not logged in).
  • Accessing user.name assumes user is an object.
  • When user is actually undefined, the engine throws a TypeError.

A safer version:

const user = getUser();

if (user) {
  console.log(user.name);
} else {
  console.log('No user found');
}

Or with optional chaining (widely supported as of 2024):

console.log(user?.name ?? 'No user found');

This is one of the most representative examples of TypeError in JavaScript because it exposes a deeper issue: your mental model of the data doesn’t match reality.


Real examples of TypeError from DOM and browser code

Front-end code is a gold mine for TypeError. The DOM API loves to return null when an element isn’t found, and developers love to forget that.

Example: Cannot read properties of null (reading 'addEventListener')

const button = document.getElementById('submit-btn');

button.addEventListener('click', () => {
  console.log('Submitted');
});
// 💥 TypeError: Cannot read properties of null (reading 'addEventListener')

Why it happens:

  • The element with ID submit-btn doesn’t exist yet (maybe the script loads in the <head> before the DOM is ready, or the ID is misspelled).
  • getElementById returns null.
  • null.addEventListener is not valid, so you get a TypeError.

How to guard against it:

document.addEventListener('DOMContentLoaded', () => {
  const button = document.getElementById('submit-btn');
  if (!button) return; // or handle the missing element explicitly

  button.addEventListener('click', () => {
    console.log('Submitted');
  });
});

This is another example of TypeError in JavaScript that shows how timing (DOM readiness) and null checks matter.


Examples of TypeError in async/await and API calls

As of 2024–2025, a lot of JavaScript TypeError questions come from async code. The pattern: you assume a network response has the shape you expect, but the API returns something else.

Example: Cannot read properties of undefined after fetch

async function loadProfile() {
  const res = await fetch('/api/profile');
  const data = await res.json();

  console.log(data.user.name); // 💥 TypeError if data.user is undefined
}
``;

Common real examples include:

- The API returns `{ error: 'Not authenticated' }` instead of `{ user: { ... } }`.
- A 500 error is returned and the JSON body differs from the happy path.

Safer pattern:

```js
async function loadProfile() {
  const res = await fetch('/api/profile');

  if (!res.ok) {
    console.error('Request failed with status', res.status);
    return;
  }

  const data = await res.json();

  if (!data.user) {
    console.warn('No user field in response', data);
    return;
  }

  console.log(data.user.name);
}

This is one of the best examples of TypeError in JavaScript from modern web apps: everything compiles, but your runtime data contract is broken.


Examples of TypeError from misusing this

this in JavaScript has caused more TypeError questions than almost any other language feature. When this is not what you think, method calls explode.

Example: Cannot read properties of undefined (reading 'length')

const counter = {
  items: [1, 2, 3],
  logCount() {
    console.log(this.items.length);
  }
};

const fn = counter.logCount;
fn(); // 💥 TypeError: Cannot read properties of undefined (reading 'length')

Why it happens:

  • When you do const fn = counter.logCount;, you detach the method from its object.
  • In non-strict mode, this may become the global object; in strict mode, this becomes undefined.
  • this.items is now undefined, and accessing .length throws a TypeError.

Safer approaches:

// Bind this explicitly
const fn = counter.logCount.bind(counter);
fn(); // logs 3

// Or use arrow functions when appropriate (for callbacks, not methods)

Frameworks like React, Vue, and old-school class components have many real examples of TypeError in JavaScript that boil down to losing this binding.


Examples include calling a non-function

Another frequent pattern: you think something is a function, but it’s not.

Example: x is not a function

const handlers = {
  onClick: null
};

function trigger() {
  handlers.onClick(); // 💥 TypeError: handlers.onClick is not a function
}

Why it happens:

  • handlers.onClick is initialized as null.
  • You call it like a function.

Better pattern:

function trigger() {
  if (typeof handlers.onClick === 'function') {
    handlers.onClick();
  }
}

A more subtle variation in modern code:

let callback = false; // or a string from user input

callback(); // 💥 TypeError: callback is not a function

These real examples of TypeError in JavaScript show up a lot when working with event systems, plugin hooks, or dependency injection.


Array and string examples of TypeError in JavaScript

Arrays and strings are another source of confusion, especially when values come from user input or external APIs.

Example: Cannot read properties of undefined (reading 'map')

function renderList(items) {
  return items.map(item => `<li>${item}</li>`).join('');
}

renderList(undefined); // 💥 TypeError: Cannot read properties of undefined (reading 'map')

Why it happens:

  • items is expected to be an array.
  • When it’s undefined, items.map is invalid.

A defensive version:

function renderList(items) {
  const safeItems = Array.isArray(items) ? items : [];
  return safeItems.map(item => `<li>${item}</li>`).join('');
}

Example: treating a string like an array of objects

const data = '{"name":"Alex"}'; // JSON string, not parsed yet

console.log(data.name.toUpperCase());
// 💥 TypeError: Cannot read properties of undefined (reading 'toUpperCase')

Here, data.name is undefined because data is a string, not an object. You meant to parse it:

const parsed = JSON.parse(data);
console.log(parsed.name.toUpperCase());

These are small mistakes, but they’re real examples of TypeError in JavaScript that show how easily types can drift when you’re dealing with strings, JSON, and arrays.


As class syntax has become standard, more developers run into TypeError when they forget new or misuse prototypes.

Example: Class constructor X cannot be invoked without 'new'

class User {
  constructor(name) {
    this.name = name;
  }
}

const u = User('Alex'); // 💥 TypeError: Class constructor User cannot be invoked without 'new'

The fix is straightforward:

const u = new User('Alex');

Example: Object.setPrototypeOf misuse

const base = { greet() { console.log('hi'); } };

const user = Object.create(null);
Object.setPrototypeOf(user, base);

user.greet(); // works

Object.setPrototypeOf(null, base); // 💥 TypeError: Object.setPrototypeOf called on null or undefined

This kind of example of TypeError in JavaScript tends to appear in lower-level libraries, polyfills, or meta-programming tools.


Modern 2024–2025 patterns that reduce TypeError

The JavaScript ecosystem in 2024–2025 has leaned heavily into tools and language features that cut down on TypeError bugs:

  • TypeScript: static type checking catches many of the examples of TypeError in JavaScript before you ever run the code. It can warn you when something might be undefined or when you call a non-function.
  • Optional chaining (?.) and nullish coalescing (??): these features make it easier to safely access nested properties without throwing TypeError.
  • Linters and static analyzers: tools like ESLint and type-aware rules can flag suspicious patterns, such as calling something that may be null or undefined.

Even if you’re writing plain JavaScript, you can adopt patterns inspired by these tools: explicit checks, clear data contracts, and small, testable functions.

For a broader perspective on error handling and debugging practices, you can look at how other fields treat error reporting and reliability. For example, the U.S. National Institute of Standards and Technology (NIST) publishes guidance on software testing and reliability engineering that, while not JavaScript-specific, reflects the same mindset of catching problems early and systematically addressing them.


How to debug TypeError quickly

When you get a TypeError, here’s a practical workflow that works well in real projects:

  • Read the full stack trace. Don’t stop at the first line. The stack tells you exactly which file and line triggered the error.
  • Log the value before using it. If user.name is failing, log user itself:

    console.log('user is', user);
    console.log('type of user is', typeof user);
    
  • Check assumptions about external data. If the value comes from a server, database, or localStorage, inspect the raw data. Many examples of TypeError in JavaScript come from assuming an API always returns the same shape.

  • Reproduce in isolation. Copy the offending code into a small snippet or a REPL (like the browser console or Node REPL) and reproduce the TypeError with hard-coded data.

This process is boring, but it’s reliable—and it’s exactly how experienced engineers handle the best examples of nasty, intermittent TypeError bugs in production.


FAQ: common questions about TypeError in JavaScript

Why do I keep getting Cannot read properties of undefined?

Because something in your code is undefined when you think it’s an object. The best examples include missing DOM elements, incomplete API responses, or variables that never got initialized. Add logging right before the line that crashes and confirm what the value actually is.

Can you give an example of preventing TypeError with optional chaining?

Yes. Suppose you have:

console.log(user.profile.address.city);

If profile or address might be missing, this can throw a TypeError. Using optional chaining:

console.log(user?.profile?.address?.city ?? 'Unknown city');

Now, instead of throwing, the expression short-circuits to 'Unknown city' when any part is null or undefined.

Are TypeError messages the same in all JavaScript engines?

No. The general idea is consistent, but wording differs. For example, Chrome and Node.js now say Cannot read properties of undefined (reading 'x'), while older environments might say Cannot read property 'x' of undefined. The underlying problem is the same, and all of these are still valid examples of TypeError in JavaScript.

How can I avoid TypeError in large applications?

Patterns that help:

  • Consistent input validation at the boundaries (HTTP handlers, message queues, form submissions).
  • Centralized schema validation (for example, using JSON Schema or a validation library) for API payloads.
  • Static typing with TypeScript or JSDoc annotations.
  • Strong linting rules that warn on suspicious patterns.

These don’t eliminate all examples of TypeError in JavaScript, but they dramatically reduce the random runtime surprises.

Are all TypeErrors bad design?

Not necessarily. Some are simple programmer mistakes; others are the language enforcing its rules. A TypeError is often a symptom that your assumptions about data or control flow are off. Treat them as feedback: each error is one more concrete example of how your code behaves in reality, not just in your head.


If you keep a mental catalog of these examples of TypeError in JavaScript—undefined properties, null DOM elements, mis-bound this, non-function calls—you’ll spot them much faster in your own stack traces. And once you can recognize the patterns, fixing them becomes almost mechanical.

Explore More Stack Overflow Errors

Discover more examples and insights in this category.

View All Stack Overflow Errors