denoland/deno · error · TypeError
Illegal invocation
Error message
Illegal invocation
What it means
reportError is a bare global function, and checkThis (ext/web/02_event.js:1712-1716) throws TypeError 'Illegal invocation' when it runs with a this that is neither null, undefined, nor globalThis. This is the standard WebIDL guard for global functions that must not be invoked as methods of another object. It fires when reportError is assigned as a property of an object or class and called through it, or invoked via call()/apply() with a non-global receiver.
Source
Thrown at ext/web/02_event.js:1716
}
const event = new ErrorEvent("error", {
cancelable: true,
message,
filename,
lineno,
colno,
error,
});
// Avoid recursing `reportException()` via error handlers more than once.
if (reportExceptionStackedCalls > 1 || globalThis_.dispatchEvent(event)) {
core.reportUnhandledException(error);
}
reportExceptionStackedCalls--;
}
function checkThis(thisArg) {
if (thisArg !== null && thisArg !== undefined && thisArg !== globalThis_) {
throw new TypeError("Illegal invocation");
}
}
// https://html.spec.whatwg.org/#dom-reporterror
function reportError(error) {
checkThis(this);
const prefix = "Failed to execute 'reportError'";
webidl.requiredArguments(arguments.length, 1, prefix);
reportException(error);
}
internals.defineEventHandler = defineEventHandler;
internals.setEventTargetData = setEventTargetData;
return {
CloseEvent,
CustomEvent,
defineEventHandler,View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Call reportError as a bare global: reportError(err) or globalThis.reportError(err).
- When aliasing it, wrap in an arrow function ((e) => reportError(e)) or bind it: const report = reportError.bind(globalThis).
- Search for assignments like obj.x = reportError and .call(/.apply wrappers around it.
Example fix
// before
const logger = { report: reportError };
logger.report(err); // TypeError: Illegal invocation
// after
const logger = { report: (e) => reportError(e) };
logger.report(err); Defensive patterns
Strategy: fallback
Try / catch
const safeReport = (e) => {
try {
return obj.report(e);
} catch (err) {
if (err instanceof TypeError && err.message === 'Illegal invocation') {
return globalThis.reportError(e);
}
throw err;
}
}; Prevention
- Invoke reportError only as a bare global call
- Alias it as an arrow function: const report = (e) => reportError(e)
- Bind when capturing: reportError.bind(globalThis)
- Avoid attaching global functions to objects/classes as methods
When it happens
Trigger: const o = { report: reportError }; o.report(err); reportError.call({}, err); class Logger { re = reportError; fire(e) { this.re(e); } } — any invocation where this binds to a non-global object.
Common situations: Wrapping reportError in logger objects, DI containers, or class methods; spy/mock frameworks that capture method references and re-invoke them with a receiver; code that enumerates globals and re-attaches them as object members.
Related errors
- Illegal invocation
- Failed to construct 'Notification': 1 argument required, but
- Invalid header: length must be 2, but is ${header.length}
- Invalid header name: "${name}"
- Cannot change header: headers are immutable
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/0e883e162e121201.
Report an issue: GitHub.