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

  1. Instantiate with new: const a = new Assert({ strict: true, skipPrototype: true }).
  2. For plain boolean assertions, use the function API instead — assert(value, message) — no construction needed.
  3. If a wrapper must construct dynamically, use Reflect.construct(Assert, [options]) rather than calling Assert directly.
  4. 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

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


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)