socketio/socket.io · error · Error

"${String(ev)}" is a reserved event name

Error message

"${String(ev)}" is a reserved event name

What it means

Thrown by the postgres-emitter's BroadcastOperator.emit() when the event name is in the emitter's RESERVED_EVENTS set (connect, connect_error, disconnect, disconnecting, newListener, removeListener). Emitters publish to other servers, and reserved names are reserved by the protocol; broadcasting them would be ambiguous and could corrupt lifecycle handling on receivers.

Source

Thrown at packages/socket.io-postgres-emitter/lib/index.ts:428

    });
    await this.emitter.pool.query("SELECT pg_notify($1, $2)", [
      this.emitter.channel,
      headerPayload,
    ]);
  }

  /**
   * Emits to all clients.
   *
   * @return Always true
   * @public
   */
  public emit<Ev extends EventNames<EmitEvents>>(
    ev: Ev,
    ...args: EventParams<EmitEvents, Ev>
  ): true {
    if (RESERVED_EVENTS.has(ev)) {
      throw new Error(`"${String(ev)}" is a reserved event name`);
    }

    // set up packet object
    const data = [ev, ...args];
    const packet = {
      type: 2, // EVENT
      data: data,
      nsp: this.emitter.nsp,
    };

    const opts = {
      rooms: [...this.rooms],
      flags: this.flags,
      except: [...this.exceptRooms],
    };

    this.publish({
      type: EventType.BROADCAST,

View on GitHub (pinned to ae7fb46e08)

Solutions

  1. Rename your broadcast event to a non-reserved name (e.g. 'user:disconnected').
  2. If you intend to notify other nodes about lifecycle changes, use a dedicated custom event consumed server-side.
  3. Check RESERVED_EVENTS (exported from the package) before emitting if event names are dynamic.

Example fix

// before
emitter.emit('disconnect', { userId });

// after
emitter.emit('user:disconnected', { userId });
Defensive patterns

Strategy: validation

Validate before calling

import { RESERVED_EVENTS } from 'socket.io-postgres-emitter';
function assertNotReserved(ev){ if(RESERVED_EVENTS.has(ev)) throw new Error(ev+' is reserved'); }

Type guard

import { RESERVED_EVENTS } from 'socket.io-postgres-emitter';
function isEmittable(ev){ return !RESERVED_EVENTS.has(ev); }

Prevention

When it happens

Trigger: Calling emitter.emit('connect'), emitter.to(room).emit('disconnect'), or any emit() with one of the six reserved event names on the socket.io-postgres-emitter.

Common situations: Using the postgres emitter to fan out a 'disconnect'/'connect' notification to all nodes instead of a custom event name; copy-pasting client event names into emitter calls; or a new reserved event added in a newer version.

Related errors


AI-assisted analysis of socketio/socket.io@ae7fb46e08 (2026-08-03). Data as JSON: /data/errors/db8f2d9db75f5576.json. Report an issue: GitHub.