websockets/ws · error · TypeError

First argument must be a valid error code number

Error message

First argument must be a valid error code number

What it means

Thrown as a TypeError by Sender.close() (sender.js:189-190) when the code argument is provided but is either not a number or fails isValidStatusCode(). Valid status codes per WebSocket close-frame rules (RFC 6455 §7.4) are: 1000-1014 (excluding 1004, 1005, 1006), and 3000-4999. Any other value — such as 0, 200, 1005, 9999, a string, or null — causes this synchronous throw that propagates to the caller of ws.close().

Source

Thrown at lib/sender.js:190

    return [target, data];
  }

  /**
   * Sends a close message to the other peer.
   *
   * @param {Number} [code] The status code component of the body
   * @param {(String|Buffer)} [data] The message component of the body
   * @param {Boolean} [mask=false] Specifies whether or not to mask the message
   * @param {Function} [cb] Callback
   * @public
   */
  close(code, data, mask, cb) {
    let buf;

    if (code === undefined) {
      buf = EMPTY_BUFFER;
    } else if (typeof code !== 'number' || !isValidStatusCode(code)) {
      throw new TypeError('First argument must be a valid error code number');
    } else if (data === undefined || !data.length) {
      buf = Buffer.allocUnsafe(2);
      buf.writeUInt16BE(code, 0);
    } else {
      const length = Buffer.byteLength(data);

      if (length > 123) {
        throw new RangeError('The message must not be greater than 123 bytes');
      }

      buf = Buffer.allocUnsafe(2 + length);
      buf.writeUInt16BE(code, 0);

      if (typeof data === 'string') {
        buf.write(data, 2);
      } else if (isUint8Array(data)) {
        buf.set(data, 2);
      } else {

View on GitHub (pinned to ae1de54330)

Solutions

  1. Use a valid WebSocket close code: 1000-1014 (except 1004/1005/1006) or 3000-4999.
  2. Ensure the code argument is a number, not a string — convert with Number() or parseInt() before calling close().
  3. Omit the code argument entirely (call ws.close() with no arguments) to send a close frame with no status code.
  4. If you need application-specific codes, use the 3000-4999 range.

Example fix

// before — invalid code (reserved)
ws.close(1005, 'going away');

// after — use a valid sendable code
ws.close(1001, 'going away');
Defensive patterns

Strategy: validation

Validate before calling

const { isValidStatusCode } = require('ws/lib/validation');

function closeSafely(ws, code, reason) {
  if (code === undefined || code === null) {
    ws.close();
    return;
  }
  if (typeof code !== 'number' || !isValidStatusCode(code)) {
    throw new TypeError(`Invalid close code: ${code}`);
  }
  ws.close(code, reason);
}

Type guard

function isValidCloseCode(code) {
  return (
    typeof code === 'number' &&
    ((code >= 1000 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006) ||
      (code >= 3000 && code <= 4999))
  );
}

Try / catch

try {
  ws.close(code, reason);
} catch (err) {
  if (err instanceof TypeError && err.message.includes('valid error code')) {
    // Fall back to a generic normal closure
    console.warn(`Invalid close code ${code}; closing with 1000 instead.`);
    ws.close(1000, reason);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling ws.close(code) or ws.close(code, reason) where code is a non-number (e.g. a string '1000', undefined paired with a reason, null) or a number outside the valid ranges. Internally, WebSocket.close() at websocket.js:322 passes code directly to sender.close(), so the throw surfaces synchronously from the ws.close() call site.

Common situations: A developer passes a custom error code like 200 or 6000 which is outside the allowed ranges. Someone passes code as a string instead of a number. A developer uses 1005/1006 (reserved/forbidden codes) thinking they are sendable. Passing null or 0 as a code. Confusing application-level error codes with WebSocket close codes.

Related errors


AI-assisted analysis of websockets/ws@ae1de54330 (2026-08-03). Data as JSON: /data/errors/21fd53d0970da278.json. Report an issue: GitHub.