{"record":{"id":"8a449514d3c08f6b","repo":"websockets/ws","slug":"unknown-parameter-key","errorCode":null,"errorMessage":"Unknown parameter \"${key}\"","messagePattern":"Unknown parameter \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/permessage-deflate.js","lineNumber":289,"sourceCode":"        } else if (key === 'server_max_window_bits') {\n          const num = +value;\n          if (!Number.isInteger(num) || num < 8 || num > 15) {\n            throw new TypeError(\n              `Invalid value for parameter \"${key}\": ${value}`\n            );\n          }\n          value = num;\n        } else if (\n          key === 'client_no_context_takeover' ||\n          key === 'server_no_context_takeover'\n        ) {\n          if (value !== true) {\n            throw new TypeError(\n              `Invalid value for parameter \"${key}\": ${value}`\n            );\n          }\n        } else {\n          throw new Error(`Unknown parameter \"${key}\"`);\n        }\n\n        params[key] = value;\n      });\n    });\n\n    return configurations;\n  }\n\n  /**\n   * Decompress data. Concurrency limited.\n   *\n   * @param {Buffer} data Compressed data\n   * @param {Boolean} fin Specifies whether or not this is the last fragment\n   * @param {Function} callback Callback\n   * @public\n   */\n  decompress(data, fin, callback) {","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/websockets/ws/blob/c791e707eab3c13dd9a261d2479c3cc4a49a6fed/lib/permessage-deflate.js#L271-L307","documentation":"Thrown by `PerMessageDeflate.normalizeParams()` when a parameter key is not one of the four recognized permessage-deflate parameters (`client_max_window_bits`, `server_max_window_bits`, `client_no_context_takeover`, `server_no_context_takeover`). Any other key in the offer is rejected because RFC 7692 defines a closed set of parameters for this extension.","triggerScenarios":"A peer sends `Sec-WebSocket-Extensions: permessage-deflate; foo=bar` (unknown parameter `foo`); `normalizeParams` (called from `accept()`) throws with the offending key interpolated.","commonSituations":"A peer advertises a vendor/non-standard parameter; a typo in a hand-built header; a future/unknown extension parameter the library does not recognize; fuzzer input.","solutions":["Restrict parameters to the four RFC 7692 keys listed above.","If you are experimenting with custom parameters, fork or extend `normalizeParams`; the public API will not accept them.","Catch the error during the handshake and close with code 1002."],"exampleFix":"// before\npmd.normalizeParams([{ unknown_param: ['1'] }]);\n\n// after — recognized parameter only\npmd.normalizeParams([{ server_max_window_bits: ['12'] }]);","handlingStrategy":"validation","validationCode":"// Only the four RFC 7692 parameters are allowed.\nconst KNOWN_PMD_PARAMS = new Set([\n  'client_max_window_bits',\n  'server_max_window_bits',\n  'client_no_context_takeover',\n  'server_no_context_takeover'\n]);\nfunction hasUnknownParams(offer) {\n  return Object.keys(offer).some((k) => !KNOWN_PMD_PARAMS.has(k));\n}","typeGuard":null,"tryCatchPattern":"try {\n  perMessageDeflate.accept(parsedOffers);\n} catch (err) {\n  if (/Unknown parameter/.test(err.message)) {\n    abortHandshake(socket, 1002);\n    return;\n  }\n  throw err;\n}","preventionTips":["Restrict permessage-deflate parameters to the four RFC 7692 keys.","Whitelist parameter names before calling `accept()` on untrusted offers.","Treat unknown parameters as a protocol error (close 1002)."],"tags":["websocket","compression","permessage-deflate","negotiation","validation","rfc7692"],"backgroundTag":null,"analyzedSha":"c791e707eab3c13dd9a261d2479c3cc4a49a6fed","analyzedAt":"2026-08-06T19:07:51.047Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}