websockets/ws · error · TypeError

Invalid value for parameter "${key}": ${value}

Error message

Invalid value for parameter "${key}": ${value}

What it means

Thrown as a TypeError by normalizeParams() (permessage-deflate.js:256-261) when a client_max_window_bits parameter has a value that is not the boolean true and is not an integer in the range [8, 15]. The value is coerced with the unary + operator and checked with Number.isInteger; values like '7', '16', 'abc', '10.5', or '' all fail. RFC 7692 restricts the window-bits parameter to 9-15, but ws's normalizeParams enforces 8-15 here.

Source

Thrown at lib/permessage-deflate.js:259

   * @return {Array} The offers/response with normalized parameters
   * @private
   */
  normalizeParams(configurations) {
    configurations.forEach((params) => {
      Object.keys(params).forEach((key) => {
        let value = params[key];

        if (value.length > 1) {
          throw new Error(`Parameter "${key}" must have only a single value`);
        }

        value = value[0];

        if (key === 'client_max_window_bits') {
          if (value !== true) {
            const num = +value;
            if (!Number.isInteger(num) || num < 8 || num > 15) {
              throw new TypeError(
                `Invalid value for parameter "${key}": ${value}`
              );
            }
            value = num;
          } else if (!this._isServer) {
            throw new TypeError(
              `Invalid value for parameter "${key}": ${value}`
            );
          }
        } else if (key === 'server_max_window_bits') {
          const num = +value;
          if (!Number.isInteger(num) || num < 8 || num > 15) {
            throw new TypeError(
              `Invalid value for parameter "${key}": ${value}`
            );
          }
          value = num;
        } else if (

View on GitHub (pinned to ae1de54330)

Solutions

  1. Ensure the client_max_window_bits value (if numeric) is an integer between 8 and 15 inclusive.
  2. If the parameter is a capability flag (no value), use the bare form 'client_max_window_bits' (parsed as true) rather than assigning a number.
  3. Fix the peer that sends the out-of-range value.
  4. If you cannot control the peer, disable perMessageDeflate to avoid the negotiation.

Example fix

// before — value out of range
const header = 'permessage-deflate; client_max_window_bits=7';

// after
const header = 'permessage-deflate; client_max_window_bits=10';
Defensive patterns

Strategy: validation

Validate before calling

// Validate that client_max_window_bits (if numeric) is an integer in [8, 15]
function isValidClientMaxWindowBits(value) {
  if (value === true) return true;
  const num = Number(value);
  return Number.isInteger(num) && num >= 8 && num <= 15;
}

Type guard

function isValidWindowBitsValue(value) {
  if (value === true) return true;
  return typeof value === 'number' || /^\d+$/.test(String(value));
}

Try / catch

try {
  perMessageDeflate.normalizeParams(configurations);
} catch (err) {
  if (err instanceof TypeError && err.message.includes('client_max_window_bits')) {
    console.warn('Invalid client_max_window_bits value:', err.message);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: normalizeParams() is called with a configuration where client_max_window_bits is set to a value outside [8, 15] or a non-integer string. This comes from a header like 'permessage-deflate; client_max_window_bits=7', '...=16', '...=abc', or '...=10.5' received from a peer.

Common situations: A non-compliant client/server sends a window-bits value outside the valid range. A developer hard-codes an incorrect value. A corrupted header passes a non-numeric value. A version mismatch where a peer uses a range the other side doesn't accept.

Related errors


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