ERR_EVENT_RECURSION
Node.jsERRORNotableEventHIGH confidence

Recursive event dispatch detected

Production Risk

Low — only affects EventTarget (not EventEmitter); defer re-dispatches to avoid recursion.

What this means

Thrown when an EventTarget event dispatch recursively triggers the same event on the same target. The Web-compatible EventTarget API (used in Node.js for some built-ins) does not permit re-entrancy in event dispatch.

Why it happens
  1. 1An event listener dispatching the same event type on the same EventTarget synchronously
  2. 2Calling dispatchEvent() inside an event listener for the same event
How to reproduce

Triggered when EventTarget.dispatchEvent() is called recursively for the same event on the same target.

trigger — this will error
trigger — this will error
const { EventTarget, Event } = require('events');
const et = new EventTarget();
et.addEventListener('test', () => {
  et.dispatchEvent(new Event('test')); // recursive dispatch — throws
});
et.dispatchEvent(new Event('test'));

expected output

Error [ERR_EVENT_RECURSION]: The event "test" is already being dispatched on the target

Fix

Use setImmediate or queueMicrotask to defer re-dispatch

WHEN When an event handler must trigger the same event

Use setImmediate or queueMicrotask to defer re-dispatch
et.addEventListener('test', (event) => {
  setImmediate(() => {
    et.dispatchEvent(new Event('test')); // deferred — no recursion
  });
});

Why this works

Deferring the dispatch to the next iteration of the event loop breaks the synchronous recursion.

Code examples
Triggerjs
const { EventTarget, Event } = require('events');
const et = new EventTarget();
et.addEventListener('test', () => {
  et.dispatchEvent(new Event('test')); // recursive dispatch — throws
});
et.dispatchEvent(new Event('test'));  // this triggers ERR_EVENT_RECURSION
Handle in try/catchjs
try {
  // operation that may throw ERR_EVENT_RECURSION
  riskyOperation()
} catch (err) {
  if (err.code === 'ERR_EVENT_RECURSION') {
    console.error('ERR_EVENT_RECURSION:', err.message)
  } else {
    throw err
  }
}
Defensive pattern to avoid itjs
// Validate inputs before calling the operation
function safe_err_event_recursion(...args) {
  // validate args here
  return performOperation(...args)
}
What not to do

Synchronously dispatch the same event inside its own listener

EventTarget does not support re-entrant dispatch; it detects and prevents infinite recursion.

Sources
Official documentation ↗

Node.js Error Codes Documentation

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All Node.js errors