TypeError: x is not a function
Node.js · updated 2026-11-02
Thrown at the call site when the thing before the parentheses isn't a function. V8 prints the expression it tried to call, for example TypeError: db.findUser is not a function, which tells you exactly which name to check.
TypeError: stripe.customers.retreive is not a function
at getCustomer (/srv/app/billing.js:18:36)
at async handler (/srv/app/routes/account.js:42:20)Quick fix
Log typeof the value you are calling and, for imports, console.log the whole module object. Most of the time it is a misspelled method, a default import of a module that only has named exports (or the reverse), or a CommonJS module loaded from ESM that wraps everything in .default.
- Read the exact expression in the message; it names what was called.
- Log typeof that value and, for an import, the module object itself.
- Check the spelling of the method against the library docs.
- Match the import style to the module's exports: import x from vs import { x } from vs require().
- If the value comes from data (JSON, props, a callback argument), check it is passed and is a function before calling.
// Wrong: the module has no default export, so this is undefined
import slugify from './utils/slugify';
slugify('Hello'); // TypeError: slugify is not a function
// Right: use the named export
import { slugify } from './utils/slugify';
// CommonJS package loaded from ESM: the function may live on .default
import pkg from 'some-cjs-package';
const fn = typeof pkg === 'function' ? pkg : pkg.default;Why it happens
Default vs named import mismatch
import x from './mod' takes the default export; if the module only has named exports, x is undefined. The reverse also happens. TypeScript with esModuleInterop off, or bundlers that wrap CommonJS, make this easy to get wrong.
Misspelled or removed method
A typo (retreive, forEach on an object), or a library upgrade that renamed or removed a method. The call worked in an older version or on another branch.
Calling a method on the wrong type
Array methods on something that isn't an array: .map on an object, a NodeList or a value from JSON that is null. document.querySelectorAll returns a NodeList, which has forEach but not map.
Circular imports
Two modules import each other, so one of them reads the other before it finished loading and gets undefined for an export that exists. It usually shows up after a refactor and only for one import order.
A prop or callback that was never passed
A React component calls props.onSave() or a function calls its callback argument, but the caller did not pass one. The error points at the call inside the component, not at the missing prop.
Other fixes
- Turn on TypeScript strict mode so a call on a possibly undefined value fails at build time.
- Use optional calls for genuinely optional callbacks: onSave?.()
- Break circular imports by moving the shared code into a third module.
Same error, other wording
- TypeError: Cannot read properties of undefined (reading 'map')
- TypeError: (0 , _utils.slugify) is not a function
- TypeError: x.map is not a function
Let your coding agent catch the next one
Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:
> Find the "is not a function" TypeErrors in production, show the call site and the import or value behind it, check the module exports and library version, and fix the import or the value at its source.
Related errors
- TypeError: Cannot read properties of undefined (reading 'x')
- Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported.
- RangeError: Maximum call stack size exceeded
References: MDN: TypeError: "x" is not a function, Node.js: Modules, CommonJS and ECMAScript interop