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
- Ensure the client_max_window_bits value (if numeric) is an integer between 8 and 15 inclusive.
- 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.
- Fix the peer that sends the out-of-range value.
- 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
- Ensure client_max_window_bits numeric values are integers in the 8-15 range.
- Use the bare-flag form (no '=value') when only advertising support.
- Validate window-bits values before constructing offers or responses.
- Treat peer headers as untrusted and wrap accept() in try-catch.
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
- Unknown parameter "${key}"
- None of the extension offers can be accepted
- Unexpected parameter "client_no_context_takeover"
- Unexpected or invalid parameter "client_max_window_bits"
- Parameter "${key}" must have only a single value
AI-assisted analysis of websockets/ws@ae1de54330 (2026-08-03).
Data as JSON: /data/errors/693f243481802dce.json.
Report an issue: GitHub.