denoland/deno · error · TypeError
ERR_CONSTRUCT_CALL_REQUIRED
ERR_CONSTRUCT_CALL_REQUIRED
Error message
Class constructor Assert cannot be invoked without `new`
What it means
Deno's node:assert polyfill exposes the configurable Assert constructor (mirroring newer Node.js where assert can be instantiated with options such as strict, skipPrototype, and diff). Like any class constructor, it must be invoked with new; the explicit !new.target check throws ERR_CONSTRUCT_CALL_REQUIRED with the message 'Class constructor Assert cannot be invoked without `new`'. This is deliberately a TypeError-style misuse error, not an assertion failure.
Solutions
- Instantiate with new: const a = new Assert({ strict: true, skipPrototype: true }).
- For plain boolean assertions, use the function API instead — assert(value, message) — no construction needed.
- If a wrapper must construct dynamically, use Reflect.construct(Assert, [options]) rather than calling Assert directly.
- Raise the bundler/transpiler target to ES2015+ so `new` on class constructors is preserved verbatim.
Example fix
// before
const strictAssert = Assert({ strict: true });
// after
const strictAssert = new Assert({ strict: true }); Defensive patterns
Strategy: validation
Validate before calling
// Always instantiate the configurable assert explicitly
const opts = { strict: true, skipPrototype: false };
const a = new Assert(opts); // never Assert(opts) Type guard
// Note: probing constructibility by constructing has side effects; treat as a // documentation-level contract instead of a runtime guard for Assert specifically. // For generic helpers: use `new.target`-safe invocation via Reflect.construct. const constructAssert = (options) => Reflect.construct(Assert, [options]);
Try / catch
try {
const a = Assert(opts); // wrong form
} catch (e) {
if (e.code === 'ERR_CONSTRUCT_CALL_REQUIRED') {
return new Assert(opts); // recover by constructing properly
}
throw e;
} Prevention
- Always use `new` with the Assert constructor; keep the plain function form assert(value, message) for simple assertions.
- Keep bundler/transpiler targets at ES2015 or higher so class construction is not lowered to plain calls.
- When wrapping constructors dynamically, use Reflect.construct instead of invoking them as functions.
When it happens
Trigger: Calling the constructor as a plain function: Assert({ strict: true }) instead of new Assert({ strict: true }). Also reached when a bundler or transpiler lowers class construction into a plain call (Assert.call(...) / _super.call patterns), or when the constructor is extracted and invoked detached from new (e.g. const make = Assert; make(opts)).
Common situations: Code ported from Node versions where assert was only a plain function, so authors assume a factory call works; esbuild/babel output with targets below ES2015 rewriting class instantiation; copy-pasting docs snippets that dropped the new keyword; helper wrappers that forward constructor arguments without using Reflect.construct.
Related errors
- ERR_AMBIGUOUS_ARGUMENT
- ERR_ASSERTION
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_RETURN_VALUE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/d2dbd14476eb2320.
Report an issue: GitHub.
Appendix: source
Thrown at ext/node/polyfills/assert.ts:71
ObjectPrototypeIsPrototypeOf,
ReflectApply,
ReflectHas,
RegExpPrototypeExec,
SafeArrayIterator,
StringPrototypeIndexOf,
StringPrototypeSlice,
StringPrototypeSplit,
String,
Symbol,
} = primordials;
const kOptions = Symbol("options");
const NO_EXCEPTION_SENTINEL = {};
function Assert(options) {
if (!new.target) {
throw new ERR_CONSTRUCT_CALL_REQUIRED("Assert");
}
options = ObjectAssign({
__proto__: null,
strict: true,
skipPrototype: false,
}, options);
const allowedDiffs = ["simple", "full"];
if (options.diff !== undefined) {
validateOneOf(options.diff, "options.diff", allowedDiffs);
}
this.AssertionError = AssertionError;
ObjectDefineProperty(this, kOptions, {
__proto__: null,
value: options,
enumerable: false,View on GitHub (pinned to 9ad36f7a2c)