denoland/deno · error · TypeError
ERR_INVALID_THIS
ERR_INVALID_THIS
Error message
Value of "this" must be of type Event
What it means
Event implements the nodejs.util.inspect.custom protocol used by util.inspect/console.log. That hook first verifies that its `this` is a genuine Event (constructed with the internal brand); when invoked on a foreign object it throws ERR_INVALID_THIS rather than reading missing internal slots. It fires when the custom-inspect method is extracted and called unbound, or when a non-Event object reaches inspect while carrying Event's prototype.
Source
Thrown at ext/node/polyfills/internal/event_target.mjs:131
allowArray: true,
allowFunction: true,
nullable: true,
});
const { cancelable, bubbles, composed } = { ...options };
this[kCancelable] = !!cancelable;
this[kBubbles] = !!bubbles;
this[kComposed] = !!composed;
this[kType] = `${type}`;
this[kDefaultPrevented] = false;
this[kTimestamp] = performance.now();
this[kPropagationStopped] = false;
this[kTarget] = null;
this[kIsBeingDispatched] = false;
}
[customInspectSymbol](depth, options) {
if (!isEvent(this)) {
throw new ERR_INVALID_THIS("Event");
}
const name = this.constructor.name;
if (depth < 0) {
return name;
}
const opts = ObjectAssign({}, options, {
depth: NumberIsInteger(options.depth) ? options.depth - 1 : options.depth,
});
return `${name} ${
inspect({
type: this[kType],
defaultPrevented: this[kDefaultPrevented],
cancelable: this[kCancelable],
timeStamp: this[kTimestamp],
}, opts)
}`;View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Bind the hook when extracting: const show = ev[Symbol.for('nodejs.util.inspect.custom')].bind(ev)
- Do not reuse Event's prototype methods to format foreign objects - write your own inspect function
- Build test doubles as real Events (construct then mutate) instead of Object.create(Event.prototype)
- If hit from console.log, find the object whose prototype chain includes Event.prototype but that was never constructed as an Event
Example fix
// before
const inspectKey = Symbol.for('nodejs.util.inspect.custom');
const show = ev[inspectKey];
show.call({}); // ERR_INVALID_THIS: Value of "this" must be of type Event
// after
const show = ev[inspectKey].bind(ev);
show(); // renders the event Defensive patterns
Strategy: try-catch
Validate before calling
const INSPECT_KEY = Symbol.for('nodejs.util.inspect.custom');
function inspectEvent(ev) {
if (!(ev instanceof Event)) throw new TypeError('inspectEvent expects an Event');
return ev[INSPECT_KEY].bind(ev)();
} Type guard
const isNodeEvent = (v) => v instanceof Event; // use before calling Event-only hooks
Try / catch
try {
text = inspect(obj);
} catch (e) {
if (e?.code === 'ERR_INVALID_THIS') text = String(obj); // not a real Event; fall back
else throw e;
} Prevention
- Bind methods extracted from objects before passing them as callbacks
- Build test doubles as real constructed Events, not prototype clones
- Never borrow Event's inspect hook to format foreign objects - write your own formatter
When it happens
Trigger: Extracting and calling the hook directly: Event.prototype[Symbol.for('nodejs.util.inspect.custom')].call({}); passing the method as a callback: arr.map(ev[inspectKey]) so `this` is undefined; console.log on an object that mimics/shares Event.prototype without being constructed via new Event().
Common situations: Passing inspect methods around as first-class functions (lost binding); test doubles and mock libraries creating Event-like fakes by prototype assignment; adapters that borrow prototype methods to format arbitrary objects.
Related errors
- ERR_INVALID_THIS
- Expected data to be a string, Buffer, Uint8Array, or ArrayBu
- ERR_INSPECTOR_ALREADY_CONNECTED
- ERR_INSPECTOR_NOT_WORKER
- ERR_INSPECTOR_NOT_CONNECTED
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/2fdebc831416fc9c.
Report an issue: GitHub.