JavaScript “is not a function”: Find What You’re Actually Calling

TypeError: x is not a function means JavaScript resolved the call target, but the runtime value at that call site is not callable. Start with the exact call expression and inspect the receiver/property/value immediately before it. Do not add a guard, rename a method, or change import syntax until you know what value replaced or failed to provide the expected function.

JavaScriptBrowsers · Node.jsLast reviewed Oct 29, 2026
🎯 You’re likely in the right place if:
The console shows TypeError: ... is not a function.The failing code uses parentheses like value() or object.method().The identifier exists, but its runtime value may be a string, object, undefined property or other non-callable value.
Choose the path that matches what you see
typeof value is not “function”Trace where the value was assigned or returned.
object.method exists but is not callableInspect the receiver and property value at the failing call; trace where that property was created or overwritten.
Reading object.method already throwsThe receiver may be null/undefined. Follow the separate property-access TypeError instead of this callable-value guide.
Imported value has the wrong shapeCompare default vs named exports with the module’s real export declaration.
A callback is expectedPass a function, not the result of calling that function or a non-function value.
Difficulty: Easy–ModerateRisk: Low first
🔎 First check — inspect the exact call target

First-party reproduction run on Oct 29, 2026 in Node.js v24.22.1: calling a number named formatValue produced “TypeError: formatValue is not a function”; replacing it with formatValue as a function printed “function 42”. For your own failure, inspect the exact call target immediately before the failing line. For object.method(), inspect both the receiver and object.method; an overwritten method or wrong object may need a different fix.

node -e 'const formatValue = 42; formatValue()' # TypeError: formatValue is not a function node -e 'const formatValue = value => String(value); console.log(typeof formatValue, formatValue(42))' # function 42

Interpret: typeof ... === "function" means that captured target is callable. Any other value tells you what the runtime is actually trying to call. If the receiver itself is null/undefined in the original expression, classify that property-access failure separately.

Did the runtime type explain the failure?
ADSENSE · reserved slot after the first useful step

Why this happens

This TypeError is about callability at the failing call site. Common causes include the wrong receiver type, a property that is absent or contains data instead of a function, a function name/property overwritten later, API/version mismatch, or an import whose runtime shape differs from what the caller expects. This is later than x is not defined: the name/expression resolved far enough for JavaScript to attempt a call.

Diagnose before changing more

1
Is the method valid for this object type?
For example, array methods such as map() are not available on plain objects.
2
Was the function name overwritten?
A later assignment can replace a function with a string, object or other value.
3
Does the import match the export style?
Default and named imports can produce a different runtime value than your code expects.
4
Did the value cross an API/data boundary?
JSON, network payloads and structured data do not preserve executable function values. Confirm the caller is not treating data as an object instance/API with methods.
5
Does it fail only after a library/framework upgrade?
Check the API for the installed version. A removed/renamed method or changed export shape should not be “fixed” with a type guard.
6
Only bundled/transpiled output fails?
Inspect the runtime import/object shape in the failing build before changing source import syntax or enabling interop workarounds.

Fix #2 — correct the object or method being called

Confirm the receiver has the method you are invoking. If the value should be an array, function or class instance, trace where that value is created and validate its shape before the call.

if (typeof handler === 'function') { handler(); }
🟡 Guard ≠ root-cause fix: A typeof handler === 'function' guard is appropriate only when “no callable handler” is a valid state. If the function is required by the program contract, silently skipping the call hides the defect; fix the producer, receiver, API usage or import instead.

Verify: Run the same call again. The value immediately before the call should be the expected object/function type, and the original TypeError should be gone.

Did Fix #2 work?

Fix #3 — align import/export shape and avoid name collisions

If the value comes from a module, verify whether it is a default export, named export or namespace object. Also check that a local variable has not reused the function’s name.

// named export export function runTask() {} import { runTask } from './task.js';
🟡 Keep it reversible: Do not change import syntax blindly; match the module’s actual export declaration.

Verify: Log the imported value once after changing the import. It should have the export shape you expect before you call it.

Did Fix #3 work?

What not to do

Do not add optional chaining or a type guard only to hide an unexpected value; use it only when “missing” is a valid state.Do not rename methods by trial and error. Confirm the receiver type and API first.Do not switch default/named import syntax unless it matches the module’s actual exports.Do not use optional chaining or a typeof guard to silently skip a function that the application contract requires.Do not treat JSON/network data as though it retained class-instance methods or function properties.Do not blame the method name until you have captured the actual receiver and property value at the failing call site.Do not keep applying this guide if the receiver itself is null/undefined and property access fails before the call.

Still seeing the error?

If the value is a function when logged but the error still appears elsewhere, inspect the exact stack trace. A different code path may be calling another property with the same name on a different object.

Before escalating, capture:the exact TypeError and first relevant stack framethe runtime value and typeof result immediately before the callthe receiver/object shape if this is object.method()the module export and import lines if modules are involvedthe exact call expression plus receiver and property value immediately before itwhere the non-callable value was assigned/returned or crossed a data/API boundaryinstalled library/framework version if the method/API changed across versions

References and related guides

Still stuck? Ask the community

Share your operating system, software version, exact error text, and which fix you already tried. Another reader may have seen the same setup.

Keep it safe: never post passwords, API keys, access tokens, recovery codes, license keys, private URLs, or confidential logs.
Powered by GitHub DiscussionsSign in with GitHub to comment. Reading comments does not require sign-in.

Loading community discussion…