All posts
javascripttypeerrordebugging

TypeError: X is not a function — What It Means and How to Fix It

"TypeError: X is not a function" explained — why it happens, a real code example that triggers it, and the exact fix.

SR

Suhail Roushan

August 6, 2026

·
3 min read
·
0 views

"TypeError: X is not a function" means JavaScript tried to invoke something as a function, but that something isn't callable.

What "TypeError: X is not a function" Means

This error occurs when you add parentheses () after a value that doesn't have a [[Call]] internal method. In plain terms: you're treating a non-function like a function. The X in the message is whatever variable, property, or expression you tried to call.

Why It Happens

Three causes cover 95% of real-world occurrences:

  1. Undefined or null values: You're calling a method on something that doesn't exist yet (e.g., user.getName() where user is undefined).
  2. Wrong import or destructuring: You imported a default export as a named export, or vice versa. The value you're calling is actually an object or module namespace, not a function.
  3. Overwritten function references: You assigned a non-function value to a variable that previously held a function (often in loops or callbacks).

Example Code That Triggers It

Here's a runnable example that produces this exact error in Node.js or the browser console:

// This triggers "TypeError: user.getName is not a function"
const user = {
  name: "Alice",
  age: 30,
};

console.log(user.getName()); // TypeError: user.getName is not a function

The user object never defined getName, so it's undefined. Calling undefined() throws the error.

How to Fix It

The fix depends on the cause. For the example above, either define the method or check it exists:

const user = {
  name: "Alice",
  age: 30,
  getName() {
    return this.name;
  },
};

// Safe call with optional chaining
console.log(user.getName?.() ?? "No method defined");

For the import case (common in Next.js and React), verify your export/import pairing:

// Wrong: default export imported as named
import { Button } from "./Button"; // Button is the module object

// Correct:
import Button from "./Button"; // default export

Common Mistakes That Cause This

Mistake 1: Calling array methods on array-like objects. document.querySelectorAll() returns a NodeList, not an array. Calling nodeList.map() throws this error because NodeList doesn't have map in older browsers. Use Array.from(nodeList) first.

Mistake 2: Not binding this in callbacks. When you pass a method as a callback (e.g., setTimeout(obj.method, 100)), this becomes undefined in strict mode. The method tries to access this.something, which fails — but the error you see is often "X is not a function" when this itself is undefined.

When Should You Worry About This?

You should worry when this error appears in production, not just during development. In development, it usually means a typo or missing method — easy to spot. In production, it often indicates a race condition: data hasn't loaded yet, so you're calling a method on an empty object. If you see it intermittently, check whether your API responses or state updates are arriving before the code that uses them. Adding optional chaining (?.) or defensive checks is a legitimate fix, not a hack — it signals you understand the data flow.

Next time you see "TypeError: X is not a function", check what X actually is first — console.log(X) before the call. Nine times out of ten, it's undefined or an object, and the fix is obvious from there.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch