{"record":{"id":"38448e5ee28ba2d6","repo":"websockets/ws","slug":"unexpected-parameter-client-no-context-takeover","errorCode":null,"errorMessage":"Unexpected parameter \"client_no_context_takeover\"","messagePattern":"Unexpected parameter \"client_no_context_takeover\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/permessage-deflate.js","lineNumber":219,"sourceCode":"\n    return accepted;\n  }\n\n  /**\n   * Accept the extension negotiation response.\n   *\n   * @param {Array} response The extension negotiation response\n   * @return {Object} Accepted configuration\n   * @private\n   */\n  acceptAsClient(response) {\n    const params = response[0];\n\n    if (\n      this._options.clientNoContextTakeover === false &&\n      params.client_no_context_takeover\n    ) {\n      throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n    }\n\n    if (!params.client_max_window_bits) {\n      if (typeof this._options.clientMaxWindowBits === 'number') {\n        params.client_max_window_bits = this._options.clientMaxWindowBits;\n      }\n    } else if (\n      this._options.clientMaxWindowBits === false ||\n      (typeof this._options.clientMaxWindowBits === 'number' &&\n        params.client_max_window_bits > this._options.clientMaxWindowBits)\n    ) {\n      throw new Error(\n        'Unexpected or invalid parameter \"client_max_window_bits\"'\n      );\n    }\n\n    return params;\n  }","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/websockets/ws/blob/c791e707eab3c13dd9a261d2479c3cc4a49a6fed/lib/permessage-deflate.js#L201-L237","documentation":"Thrown by `PerMessageDeflate.acceptAsClient()` when the client set `clientNoContextTakeover: false` (it does not want context takeover disabled on its side) but the server's permessage-deflate response nevertheless includes `client_no_context_takeover`. The client treats this as an unacceptable response and aborts negotiation.","triggerScenarios":"Client created with `new WebSocket(url, { perMessageDeflate: { clientNoContextTakeover: false } })` connecting to a server whose agreed response forces `client_no_context_takeover`. Surfaces during the client-side handshake.","commonSituations":"Server and client disagree on context takeover to save memory; a server policy that always disables takeover meets a client that requires it for performance; misconfigured reverse proxy that rewrites the extension response.","solutions":["Allow the client to accept context-takeover disabling by not setting `clientNoContextTakeover: false` (or setting it `true`).","Relax the server policy so it does not force `client_no_context_takeover` on unwilling clients.","Disable compression on the client with `perMessageDeflate: false` if the policy mismatch cannot be resolved."],"exampleFix":"// before\nconst ws = new WebSocket(url, {\n  perMessageDeflate: { clientNoContextTakeover: false }\n});\n// server responds with client_no_context_takeover -> throws\n\n// after — allow takeover disabling\nconst ws = new WebSocket(url, {\n  perMessageDeflate: { clientNoContextTakeover: true }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  perMessageDeflate.accept(serverResponseOffers);\n} catch (err) {\n  if (/Unexpected parameter \"client_no_context_takeover\"/.test(err.message)) {\n    // Server forced context-takeoff disabling that the client refused.\n    // Either relax the client option or disable compression.\n    reconnectWithoutCompression(url);\n    return;\n  }\n  throw err;\n}","preventionTips":["Don't set `clientNoContextTakeover: false` on the client unless you control the server's policy too.","Make compression optional on the client so a policy mismatch falls back rather than crashing.","Catch the handshake error and reconnect with `perMessageDeflate: false` as a fallback."],"tags":["websocket","compression","permessage-deflate","negotiation","handshake","client"],"backgroundTag":null,"analyzedSha":"c791e707eab3c13dd9a261d2479c3cc4a49a6fed","analyzedAt":"2026-08-06T19:07:51.047Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}