TypeError: Client is not a constructor
Node.js · updated 2026-11-04
Thrown at the new expression when the value isn't a constructor: an object (often a module namespace), undefined, an arrow function or a plain value. In builds that transpile imports, the message shows the generated name, such as _client.default is not a constructor, which points at the import line rather than the class.
TypeError: _sdk.default is not a constructor
at createClient (/app/dist/services/payments.js:12:18)
at Object.<anonymous> (/app/dist/server.js:8:16)Quick fix
Log the imported value (console.log(typeof X, X)) at the failing line. If it's an object with a default or a named export inside, change the import: import { Client } from 'pkg' or import pkg from 'pkg' then new pkg.Client(), matching what the package exports. With CommonJS, require('pkg').default or a named property may be what you need. If it's undefined, look for a circular import.
- Print typeof and the value of the imported name right before the new call.
- Check the package README or its types for whether the class is a default export or a named export.
- Fix the import to match: default (import X from), named (import { X } from) or namespace (import * as m; new m.X()).
- In TypeScript compiled to CommonJS, turn on esModuleInterop so default imports of CommonJS packages work.
- If the value is undefined only at startup, two modules import each other: move the shared class to its own file.
// The package exports the class by name, not as default
// import Client from 'some-sdk'; // Client is the module object here
import { Client } from 'some-sdk';
const client = new Client({ apiKey: process.env.SDK_KEY });
// CommonJS: pick the right property
// const Client = require('some-sdk'); // { Client: [class], default: ... }
const { Client: CjsClient } = require('some-sdk');Why it happens
Default vs named import
The package exports the class as a named export (or under default), and the import takes the other form, so the value is the module object or undefined.
ESM and CommonJS interop
Importing a CommonJS package from ESM gives you module.exports as the default; requiring an ESM-compiled package from CommonJS puts the class under .default. Bundlers and TypeScript settings (esModuleInterop) change which one you get.
Circular import
Two modules import each other, and one runs before the other finished, so the class is still undefined when new runs. "Class extends value undefined is not a constructor or null" is the same cause.
Not a class at all
Arrow functions, async functions and plain objects cannot be called with new; a library may expose a factory (createClient()) instead of a class.
Other fixes
- After upgrading a package, check its changelog: moving from a default export to named exports is a common breaking change.
- node --trace-uncaught or source maps in production show the original import line instead of the transpiled _x.default name.
Same error, other wording
- TypeError: _sdk.default is not a constructor
- TypeError: Class extends value undefined is not a constructor or null
- TypeError: (intermediate value) is not a constructor
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 constructor" errors in production, check what the import at that line resolves to (default, named or namespace), and fix the import to match what the package exports.
Related errors
- Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported.
- Error: Cannot find module 'x'
- TypeError: x is not a function
More in Undefined, None and type errors
- TypeError: Cannot read properties of undefined (reading 'x')Node.js
- TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined.Node.js
- TypeError: Cannot convert undefined or null to objectNode.js
- TypeError: items is not iterableNode.js
- ReferenceError: x is not definedNode.js
- ERR_INVALID_ARG_TYPE: The "path" argument must be of type string. Received undefinedNode.js
- TypeError: 'NoneType' object is not subscriptablePython
- AttributeError: 'NoneType' object has no attribute 'x'Python
- TypeError: 'NoneType' object is not iterablePython
- KeyError: 'email'Python
- TypeError: unhashable type: 'list'Python
- AttributeError: 'dict' object has no attribute 'name'Python
- IndexError: list index out of rangePython
- TypeError: unsupported operand type(s) for +: 'int' and 'str'Python
- ValueError: invalid literal for int() with base 10: ''Python
- TypeError: __init__() got an unexpected keyword argument 'proxies'Python
- UnboundLocalError: cannot access local variable 'total' where it is not associated with a...Python
- RuntimeError: dictionary changed size during iterationPython
- ValueError: too many values to unpack (expected 2)Python
- TypeError: 'str' object is not callablePython
References: MDN: TypeError "x" is not a constructor, Node.js docs: ECMAScript modules (CommonJS interop), TypeScript TSConfig reference: esModuleInterop