{"record":{"id":"86ad687b96bab6d8","repo":"sidorares/node-mysql2","slug":"handshakeresponse-authtoken-must-be-a-buffer-when","errorCode":null,"errorMessage":"HandshakeResponse authToken must be a Buffer when provided","messagePattern":"HandshakeResponse authToken must be a Buffer when provided","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/packets/handshake_response.js","lineNumber":29,"sourceCode":"    this.user = handshake.user || '';\n    this.database = handshake.database || '';\n    this.password = handshake.password || '';\n    this.passwordSha1 = handshake.passwordSha1;\n    this.authPluginData1 = handshake.authPluginData1;\n    this.authPluginData2 = handshake.authPluginData2;\n    this.compress = handshake.compress;\n    this.clientFlags = handshake.flags;\n    this.mariadbExtendedClientFlags = handshake.mariadbExtendedClientFlags || 0;\n\n    // Accept pre-calculated authToken and authPluginName from caller\n    // This allows the caller to optimize by using the server's preferred auth method\n    if (\n      handshake.authToken !== undefined &&\n      handshake.authPluginName !== undefined\n    ) {\n      // Validate types to fail fast with clear errors\n      if (!Buffer.isBuffer(handshake.authToken)) {\n        throw new TypeError(\n          'HandshakeResponse authToken must be a Buffer when provided'\n        );\n      }\n      if (typeof handshake.authPluginName !== 'string') {\n        throw new TypeError(\n          'HandshakeResponse authPluginName must be a string when provided'\n        );\n      }\n      this.authToken = handshake.authToken;\n      this.authPluginName = handshake.authPluginName;\n    } else {\n      // Fallback to legacy behavior: calculate mysql_native_password token\n      // TODO: pre-4.1 auth support\n      let authToken;\n      if (this.passwordSha1) {\n        authToken = auth41.calculateTokenFromPasswordSha(\n          this.passwordSha1,\n          this.authPluginData1,","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/8b1f829d3706404ab372cf97bd77ebcf86578d97/lib/packets/handshake_response.js#L11-L47","documentation":"HandshakeResponse constructor (lib/packets/handshake_response.js:23-32) accepts an optional pre-computed authToken for fast-path auth optimization, but when BOTH authToken and authPluginName are provided it requires authToken to be a Buffer (because it is written as raw bytes at serializeResponse line 80-88). Passing any non-Buffer throws TypeError to fail fast before wire serialization.","triggerScenarios":"Constructing HandshakeResponse manually with authToken as a string or number; an auth-plugin integration returning a string token where a Buffer is required; a custom handshake wrapper that computes a token but forgets Buffer.from(...).","commonSituations":"Custom auth plugin development; monkey-patching the initial handshake; integration code that confuses the legacy password-string path with the pre-computed-token path.","solutions":["Provide authToken as a Buffer: authToken: Buffer.from(token, ...).","If you only have a password, omit authToken/authPluginName and let the constructor fall back to mysql_native_password token calculation (line 40-58).","Validate Buffer.isBuffer(authToken) before constructing HandshakeResponse."],"exampleFix":"// before\nnew HandshakeResponse({ ..., authToken: 'abc', authPluginName: 'x' });\n\n// after\nnew HandshakeResponse({ ..., authToken: Buffer.from('abc'), authPluginName: 'x' });","handlingStrategy":"type-guard","validationCode":"if (authToken !== undefined && !Buffer.isBuffer(authToken)) {\n  throw new TypeError('authToken must be a Buffer');\n}","typeGuard":"const isAuthTokenBuffer = (v) => v === undefined || Buffer.isBuffer(v);","tryCatchPattern":null,"preventionTips":["Always wrap token computation in Buffer.from(...).","Type the HandshakeResponse options strictly when integrating custom auth."],"tags":["authentication","handshake","serialization","validation"],"backgroundTag":null,"analyzedSha":"8b1f829d3706404ab372cf97bd77ebcf86578d97","analyzedAt":"2026-08-11T02:54:28.964Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}