denoland/deno · error · NodeTypeError
ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
Error message
The "event" argument must be an instance of Event. Received ${actual} What it means
dispatchEvent requires its argument to be a real Event: the polyfill checks ObjectPrototypeIsPrototypeOf(globalThis.Event.prototype, event). Plain objects ({ type: 'x' }), strings, or class instances that merely duck-type an Event all throw ERR_INVALID_ARG_TYPE. Subclasses of Event (including CustomEvent) pass the check.
Source
Thrown at ext/node/polyfills/internal/event_target.mjs:704
MapPrototypeDelete(this[kEvents], type);
}
this[kRemoveListener](root.size, type, listener, capture);
break;
}
handler = handler.next;
}
}
/**
* @param {Event} event
*/
dispatchEvent(event) {
if (!isEventTarget(this)) {
throw new ERR_INVALID_THIS("EventTarget");
}
if (!ObjectPrototypeIsPrototypeOf(globalThis.Event.prototype, event)) {
throw new ERR_INVALID_ARG_TYPE("event", "Event", event);
}
if (event[kIsBeingDispatched]) {
throw new ERR_EVENT_RECURSION(event.type);
}
this[kHybridDispatch](event, event.type, event);
return event.defaultPrevented !== true;
}
[kHybridDispatch](nodeValue, type, event) {
const createEvent = () => {
if (event === undefined) {
event = this[kCreateEvent](nodeValue, type);
event[kTarget] = this;
event[kIsBeingDispatched] = true;
}View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Wrap the payload: dispatchEvent(new CustomEvent('ping', { detail: data }))
- Use new Event(type) when no payload is needed
- Make custom event classes extend Event (or CustomEvent) so the prototype check passes
- Convert { type, detail } literals at the boundary before dispatching
Example fix
// before
target.dispatchEvent({ type: 'ping', detail: 42 });
// after
target.dispatchEvent(new CustomEvent('ping', { detail: 42 })); Defensive patterns
Strategy: type-guard
Validate before calling
function dispatch(target, typeOrEvent, detail) {
const ev = typeOrEvent instanceof Event
? typeOrEvent
: detail === undefined ? new Event(typeOrEvent) : new CustomEvent(typeOrEvent, { detail });
target.dispatchEvent(ev);
} Type guard
const isEvent = (v) => v instanceof Event; // matches the polyfill's prototype check
Try / catch
try { target.dispatchEvent(ev); } catch (e) { if (e?.code === 'ERR_INVALID_ARG_TYPE' && /event/.test(e.message)) throw new TypeError('dispatchEvent requires an Event instance'); throw e; } Prevention
- Always construct new Event/CustomEvent at the dispatch boundary; never forward plain payload objects
- Make custom event classes extend Event or CustomEvent so the prototype check passes
- Be aware the check is prototype-based: duck-typed or cross-realm objects fail even if they look like events
When it happens
Trigger: dispatchEvent({ type: 'ping', detail: 1 }); dispatchEvent('ping'); passing a payload object that was JSON round-tripped; a MockEvent class that implements the shape but does not extend Event; forwarding an EventEmitter-style { type, ... } object into an EventTarget.
Common situations: Porting EventEmitter emit('name', data) calls to EventTarget dispatch; test fixtures that fake events as literals; cross-realm or cross-copy constructs where the object came from a different context and is not a real Event instance.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ERR_EVENT_RECURSION
- ERR_INVALID_ARG_TYPE
- 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/32a5d5bea23b5a67.
Report an issue: GitHub.