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 callbackView on GitHub (pinned to ae7fb46e08)
Solutions
- Rename your custom event to something not in the reserved list (connect, connect_error, disconnect, disconnecting, newListener, removeListener).
- If you need to signal disconnection, call socket.disconnect() instead of socket.emit('disconnect').
- 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
- Never name custom events connect/connect_error/disconnect/disconnecting/newListener/removeListener on the client.
- Use socket.disconnect() to disconnect, not socket.emit('disconnect').
- Check the reserved list after upgrading socket.io-client major versions.
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
- "${String(ev)}" is a reserved event name
- "${String(ev)}" is a reserved event name
- "${String(ev)}" is a reserved event name
- "${String(ev)}" is a reserved event name
AI-assisted analysis of socketio/socket.io@ae7fb46e08 (2026-08-03).
Data as JSON: /data/errors/d309aa7d00011ef7.json.
Report an issue: GitHub.