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

  1. Bind the hook when extracting: const show = ev[Symbol.for('nodejs.util.inspect.custom')].bind(ev)
  2. Do not reuse Event's prototype methods to format foreign objects - write your own inspect function
  3. Build test doubles as real Events (construct then mutate) instead of Object.create(Event.prototype)
  4. 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

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


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/2fdebc831416fc9c. Report an issue: GitHub.