{"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":217,"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":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/websockets/ws/blob/ae1de54330cef77e487548890fabfeb9aae1d83d/lib/permessage-deflate.js#L199-L235","documentation":"Thrown by PerMessageDeflate.acceptAsClient() (permessage-deflate.js:213-217) when the client has explicitly set clientNoContextTakeover to false (disabling context takeover) but the server's negotiation response includes the client_no_context_takeover parameter. This is a protocol conflict: the client refused context takeover, yet the server insists on it.","triggerScenarios":"A WebSocket client is created with `{ perMessageDeflate: { clientNoContextTakeover: false } }` and connects to a server whose permessage-deflate response advertises client_no_context_takeover. During the client's accept() call, this mismatch is detected and the error is thrown.","commonSituations":"A client explicitly disables context takeover for memory reasons but connects to a server that always sends client_no_context_takeover in its response. A misconfigured or non-compliant server ignores the client's offer terms. A developer sets clientNoContextTakeover: false thinking it requests disabling, when actually false means 'do not allow the server to request it'.","solutions":["Remove clientNoContextTakeover: false from the client options (or set it to true/undefined) to allow the server to request context takeover disabling.","Reconfigure the server to not send client_no_context_takeover in its response when the client doesn't offer it.","Set perMessageDeflate: false on the client to skip compression negotiation entirely.","Understand the semantics: clientNoContextTakeover: true means 'request the server to disable'; false means 'reject if the server tries to set it'."],"exampleFix":"// before\nconst ws = new WebSocket('ws://host', {\n  perMessageDeflate: { clientNoContextTakeover: false }\n});\n\n// after — allow the server to request context takeover disabling\nconst ws = new WebSocket('ws://host', {\n  perMessageDeflate: { clientNoContextTakeover: true }\n});","handlingStrategy":"try-catch","validationCode":"// Before connecting, ensure clientNoContextTakeover is not set to false\n// if the server is known to send client_no_context_takeover\nfunction validateClientDeflateOpts(opts) {\n  if (opts && opts.clientNoContextTakeover === false) {\n    console.warn('clientNoContextTakeover: false will reject servers that send client_no_context_takeover');\n    return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  perMessageDeflate.accept(serverResponse);\n} catch (err) {\n  if (err.message.includes('client_no_context_takeover')) {\n    // Retype or disable compression\n    console.error('Server response incompatible with client options:', err.message);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Understand that clientNoContextTakeover: false means 'reject servers that request it' — not 'request disabling'.","Use clientNoContextTakeover: true to actively request context-takeover disabling.","Omit the option entirely if you have no specific requirement.","If connecting to a server you do not control, avoid setting restrictive boolean false options."],"tags":["websocket","permessage-deflate","compression","handshake","negotiation"],"analyzedSha":"ae1de54330cef77e487548890fabfeb9aae1d83d","analyzedAt":"2026-08-03T19:11:18.437Z","schemaVersion":2}