socketio/socket.io · error · Error

invalid payload

Error message

invalid payload

What it means

Thrown by decodeString() when the JSON payload portion of a packet parses successfully but fails the structural check in Decoder.isPayloadValid(). Each packet type requires a specific payload shape (CONNECT needs an object, DISCONNECT needs no payload, EVENT/BINARY_EVENT need an array whose first element is a string not reserved, ACK/BINARY_ACK need an array).

Source

Thrown at packages/socket.io-parser/lib/index.ts:285

      const start = i + 1;
      while (++i) {
        const c = str.charAt(i);
        if (null == c || Number(c) != c) {
          --i;
          break;
        }
        if (i === str.length) break;
      }
      p.id = Number(str.substring(start, i + 1));
    }

    // look up json data
    if (str.charAt(++i)) {
      const payload = this.tryParse(str.substr(i));
      if (Decoder.isPayloadValid(p.type, payload)) {
        p.data = payload;
      } else {
        throw new Error("invalid payload");
      }
    }

    debug("decoded %s as %j", str, p);
    return p;
  }

  private tryParse(str) {
    try {
      return JSON.parse(str, this.opts.reviver);
    } catch (e) {
      return false;
    }
  }

  private static isPayloadValid(type: PacketType, payload: any): boolean {
    switch (type) {
      case PacketType.CONNECT:

View on GitHub (pinned to ae7fb46e08)

Solutions

  1. Confirm both ends use compatible Socket.IO protocol versions so payload shapes align.
  2. Ensure EVENT payloads are arrays like ['eventName', arg1, arg2] and the event name is not reserved.
  3. Ensure CONNECT payloads are plain objects (e.g. {}) and DISCONNECT has no payload.

Example fix

// before
// malformed: EVENT with reserved name as payload[0]
decoder.add('2["connect","hi"]'); // isPayloadValid fails -> 'invalid payload'

// after
decoder.add('2["myEvent","hi"]');
Defensive patterns

Strategy: validation

Validate before calling

function payloadOk(type, payload){
  switch(type){
    case 0: return typeof payload==='object'&&payload!==null;
    case 1: return payload===undefined;
    case 4: return typeof payload==='string'||(typeof payload==='object'&&payload!==null);
    case 2: case 5: return Array.isArray(payload)&&(typeof payload[0]==='number'||(typeof payload[0]==='string'));
    case 3: case 6: return Array.isArray(payload);
    default: return false;
  }
}

Type guard

function isEventPayload(p){ return Array.isArray(p) && typeof p[0]==='string'; }

Try / catch

try { decoder.add(raw); }
catch(e){ if(/invalid payload/.test(e.message)){ return; } throw e; }

Prevention

When it happens

Trigger: A CONNECT packet whose JSON body is an array or primitive (not an object); an EVENT packet whose payload is not an array, or whose first element is a reserved event name or not a string/number; an ACK whose payload is not an array; or a DISCONNECT that carries a payload.

Common situations: A client/server version mismatch changing the payload contract; a custom producer emitting malformed JSON payloads; or a reserved event name slipping into an EVENT payload (isPayloadValid rejects reserved names at parser level too).

Related errors


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