denoland/deno · error · ConstructCallRequiredError
ERR_CONSTRUCT_CALL_REQUIRED
ERR_CONSTRUCT_CALL_REQUIRED
Error message
Cannot call constructor without `new`
What it means
DatabaseSync is an ES5-style wrapper function around the native op class so that it can validate the call form. Invoking it as a plain function (`DatabaseSync(':memory:')`) skips construction, so the wrapper checks `new.target === undefined` and throws ERR_CONSTRUCT_CALL_REQUIRED ('Cannot call constructor without `new`') before any native code runs.
Source
Thrown at ext/node/polyfills/sqlite.ts:160
typeof parsedPath === "undefined" ||
StringPrototypeIncludes(parsedPath, "\0")
) {
throw new InvalidArgTypeError(
'The "path" argument must be a string, Uint8Array, or URL without null bytes.',
);
}
return parsedPath;
};
// Using ES5 class allows custom error to be thrown
// when called without `new`.
function DatabaseSync(
path,
options,
) {
if (new.target === undefined) {
throw new ConstructCallRequiredError();
}
return ReflectConstruct(
DatabaseSyncOp,
[parsePath(path), options],
new.target,
);
}
ObjectSetPrototypeOf(DatabaseSync.prototype, DatabaseSyncOp.prototype);
ObjectSetPrototypeOf(DatabaseSync, DatabaseSyncOp);
function validateBackupOptions(options) {
if (options === undefined) {
return;
}
if (typeof options !== "object" || options === null) {
throw new InvalidArgTypeError(
'The "options" argument must be an object.',
);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Always construct with `new`: `new DatabaseSync(path)`
- Wrap in an explicit factory that forwards with new: `const connect = (path) => new DatabaseSync(path)`
- When passing constructors as callbacks, use arrow wrappers: `.map((p) => new DatabaseSync(p))`
Example fix
// before
const db = DatabaseSync('app.db');
// ERR_CONSTRUCT_CALL_REQUIRED
// after
const db = new DatabaseSync('app.db');
// or a factory wrapper
const connect = (path) => new DatabaseSync(path); Defensive patterns
Strategy: try-catch
Try / catch
try {
const db = DatabaseSync(path); // forgot `new`
} catch (e) {
if (e.code === 'ERR_CONSTRUCT_CALL_REQUIRED') {
throw new Error('DatabaseSync must be called with `new`');
}
throw e;
} Prevention
- Use `new` for every node:sqlite class (DatabaseSync, and via it StatementSync)
- Prefer small factory functions over passing constructors as callbacks
- Lint for `.map(DatabaseSync)`-style constructs that drop `new`
When it happens
Trigger: `const db = DatabaseSync('db.sqlite')` without `new`; aliasing the class (`const connect = DatabaseSync; connect(path)`) or passing it as a callback (`.map(DatabaseSync)`), which loses construct semantics.
Common situations: Porting better-sqlite3 factory-style wrappers (`connect(path)`); bundled/minified code that drops `new`; calling via `.call(null, path)`.
Related errors
- ERR_CONSTRUCT_CALL_REQUIRED
- ERR_INVALID_URL_SCHEME
- ERR_ILLEGAL_CONSTRUCTOR
- ERR_ILLEGAL_CONSTRUCTOR
- ERR_CONSTRUCT_CALL_REQUIRED
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/7b68d6692541bd22.
Report an issue: GitHub.