denoland/deno · error · TypeError
Illegal constructor
Error message
Illegal constructor
What it means
AbortSignal's constructor is gated by an internal illegalConstructorKey symbol (ext/web/03_abort_signal.js:225-229): new AbortSignal() (or instantiating a subclass, since the default key parameter never matches) throws TypeError 'Illegal constructor'. Signals are meant to come from factories — new AbortController().signal, AbortSignal.timeout(), AbortSignal.abort(), AbortSignal.any() — and the assertBranded getters pair with this guard to keep internal slots unforgeable.
Source
Thrown at ext/web/03_abort_signal.js:225
// release strong references from source signals now that abort has been delivered
if (this[sourceSignals] !== null) {
for (const weakRef of new SafeSetIterator(this[sourceSignals])) {
const sourceSignal = WeakRefPrototypeDeref(weakRef);
if (sourceSignal !== undefined && sourceSignal[activeDependents]) {
SetPrototypeDelete(sourceSignal[activeDependents], this);
}
}
}
}
[remove](algorithm) {
this[abortAlgos] && SetPrototypeDelete(this[abortAlgos], algorithm);
}
constructor(key = null) {
if (key !== illegalConstructorKey) {
throw new TypeError("Illegal constructor");
}
super();
}
get aborted() {
webidl.assertBranded(this, AbortSignalPrototype);
return this[abortReason] !== undefined;
}
get reason() {
webidl.assertBranded(this, AbortSignalPrototype);
return this[abortReason];
}
throwIfAborted() {
webidl.assertBranded(this, AbortSignalPrototype);
if (this[abortReason] !== undefined) {
throw this[abortReason];View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Create signals via factories: new AbortController().signal for controllable signals, AbortSignal.timeout(ms) for deadlines, AbortSignal.abort(reason) for pre-aborted, AbortSignal.any([...]) for composition.
- Type variables as AbortSignal and construct them only through these APIs.
- Do not subclass AbortSignal — compose behavior with AbortSignal.any or by listening to abort events.
Example fix
// before const signal = new AbortSignal(); // TypeError: Illegal constructor // after const signal = AbortSignal.timeout(5_000); // or new AbortController().signal
Defensive patterns
Strategy: fallback
Validate before calling
const signal = opts?.signal instanceof AbortSignal ? opts.signal : AbortSignal.any([AbortSignal.timeout(5_000)]);
Type guard
const isAbortSignal = (v) => v instanceof AbortSignal;
Prevention
- Build signals only via new AbortController().signal, AbortSignal.timeout(), AbortSignal.abort(), AbortSignal.any()
- Type variables as AbortSignal, never construct them
- Do not subclass AbortSignal
When it happens
Trigger: new AbortSignal(); class TimedSignal extends AbortSignal {} followed by new TimedSignal(); Reflect.construct(AbortSignal, []).
Common situations: TypeScript users writing new AbortSignal() as a placeholder; test helpers trying to fabricate pre-aborted signals; copy-pasted snippets that assume a constructible signal; polyfills from other runtimes where signals were emulated with classes.
Related errors
- 'Deno.FsFile' cannot be constructed, use 'Deno.open()' or 'D
- Deno.Kv can not be constructed: use Deno.openKv instead
- ERR_CONSTRUCT_CALL_REQUIRED
- ERR_CONSTRUCT_CALL_REQUIRED
- ERR_ILLEGAL_CONSTRUCTOR
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/1341fd73d6edad81.
Report an issue: GitHub.