socketio/socket.io · error · Error

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

Error message

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

What it means

Thrown by the client Socket.emit() when the event name passed is one of the reserved events: connect, connect_error, disconnect, disconnecting, newListener, removeListener (defined in RESERVED_EVENTS at socket.ts:90). These events are reserved because they are emitted by the library itself to signal lifecycle/EventEmitter internals; allowing user emission would corrupt state and confuse listeners.

Source

Thrown at packages/socket.io-client/lib/socket.ts:415

   * @example
   * socket.emit("hello", "world");
   *
   * // all serializable datastructures are supported (no need to call JSON.stringify)
   * socket.emit("hello", 1, "2", { 3: ["4"], 5: Uint8Array.from([6]) });
   *
   * // with an acknowledgement from the server
   * socket.emit("hello", "world", (val) => {
   *   // ...
   * });
   *
   * @return self
   */
  public emit<Ev extends EventNames<EmitEvents>>(
    ev: Ev,
    ...args: EventParams<EmitEvents, Ev>
  ): this {
    if (RESERVED_EVENTS.hasOwnProperty(ev)) {
      throw new Error('"' + ev.toString() + '" is a reserved event name');
    }

    args.unshift(ev);

    if (this._opts.retries && !this.flags.fromQueue && !this.flags.volatile) {
      this._addToQueue(args);
      return this;
    }

    const packet: any = {
      type: PacketType.EVENT,
      data: args,
    };

    packet.options = {};
    packet.options.compress = this.flags.compress !== false;

    // event ack callback

View on GitHub (pinned to ae7fb46e08)

Solutions

  1. Rename your custom event to something not in the reserved list (connect, connect_error, disconnect, disconnecting, newListener, removeListener).
  2. If you need to signal disconnection, call socket.disconnect() instead of socket.emit('disconnect').
  3. If you need to exchange lifecycle-like information, use a distinct event name such as 'user:left'.

Example fix

// before
socket.emit('disconnect');

// after
socket.emit('user:left');
// or, to actually close the connection:
socket.disconnect();
Defensive patterns

Strategy: validation

Validate before calling

const RESERVED = new Set(['connect','connect_error','disconnect','disconnecting','newListener','removeListener']);
function assertEmittable(ev){
  if(RESERVED.has(ev)) throw new Error(ev+' is reserved');
}

Type guard

function isEmittableEvent(ev){
  return !['connect','connect_error','disconnect','disconnecting','newListener','removeListener'].includes(ev);
}

Prevention

When it happens

Trigger: Calling socket.emit('connect'), socket.emit('disconnect'), socket.emit('connect_error'), socket.emit('disconnecting'), socket.emit('newListener'), or socket.emit('removeListener') on a client Socket instance.

Common situations: Naming a custom event that collides with a lifecycle event (e.g. socket.emit('disconnect') to 'tell' the server it left); copy-pasting a server-side event name to the client without checking the reserved list; or upgrading socket.io-client across a major version that added a new reserved event.

Related errors


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