denoland/deno · error · ERR_ILLEGAL_CONSTRUCTOR
ERR_ILLEGAL_CONSTRUCTOR
ERR_ILLEGAL_CONSTRUCTOR
Error message
Illegal constructor
What it means
The Histogram class exported from node:perf_hooks is intentionally not user-constructable: its constructor needs an internal handle and throws ERR_ILLEGAL_CONSTRUCTOR when handle === undefined (i.e. any external `new` call). Histogram instances are only meant to be obtained from monitorEventLoopDelay() or createHistogram().
Source
Thrown at ext/node/polyfills/perf_hooks.js:325
function getHistogramCloneId(histogram) {
if (histogram[_cloneId] === undefined) {
histogram[_cloneId] = nextHistogramCloneId++;
}
MapPrototypeSet(
histogramCloneRegistry,
histogram[_cloneId],
histogram[_handle],
);
return histogram[_cloneId];
}
// Public, JS-side Histogram class - `instanceof` works against both
// `monitorEventLoopDelay()` results and `createHistogram()` results.
class Histogram {
constructor(handle) {
// Intentionally not user-constructable.
if (handle === undefined) {
throw new ERR_ILLEGAL_CONSTRUCTOR();
}
this[_handle] = handle;
}
get count() {
return this[_handle].count;
}
get countBigInt() {
return this[_handle].countBigInt;
}
get min() {
if (this.max === 0) return EMPTY_HISTOGRAM_MIN;
return this[_handle].min;
}
get minBigInt() {
if (this.max === 0) return EMPTY_HISTOGRAM_MIN_BIGINT;
return BigInt(this[_handle].minBigInt);
}View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Get instances from factories: perf_hooks.createHistogram() or perf_hooks.monitorEventLoopDelay()
- For tests, create a real histogram via createHistogram() and record() synthetic values into it
- Replace subclassing with composition: wrap a real histogram instance instead of extending Histogram
Example fix
// before
const h = new perf_hooks.Histogram();
// after
const { createHistogram } = require("node:perf_hooks");
const h = createHistogram(); Defensive patterns
Strategy: validation
Validate before calling
const { createHistogram } = require("node:perf_hooks");
const h = createHistogram(); // factories only — never `new Histogram()` Type guard
const RecordableHistogram = require("node:perf_hooks").createHistogram().constructor;
const isHistogramInstance = (v) => v instanceof RecordableHistogram; Try / catch
try {
const h = new perf_hooks.Histogram();
} catch (err) {
if (err.code === "ERR_ILLEGAL_CONSTRUCTOR") {
h = perf_hooks.createHistogram();
} else throw err;
} Prevention
- Treat exported perf_hooks classes as opaque — obtain instances only from createHistogram()/monitorEventLoopDelay()
- Lint for `new perf_hooks.` in code review
- In tests, build fixtures from real factory instances
When it happens
Trigger: new perf_hooks.Histogram(); new (require("perf_hooks")).Histogram(); subclassing with class MyH extends perf_hooks.Histogram { constructor() { super(); } } — the subclass path also hits the undefined-handle branch.
Common situations: Trying to fabricate a histogram for tests or seeding; adapting older blog samples referencing internal IntervalHistogram; TypeScript code instantiating the exported type directly.
Related errors
- ERR_OUT_OF_RANGE
- Unable to deserialize RecordableHistogram
- Empty filepath.
- resolve hook must return { shortCircuit: true } or call next
- load hook must return { shortCircuit: true } or call nextLoa
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/091fb65deabd60f8.
Report an issue: GitHub.