sidorares/node-mysql2 · error · TypeError
HandshakeResponse authPluginName must be a string when provi
Error message
HandshakeResponse authPluginName must be a string when provided
What it means
When a caller supplies both `authToken` and `authPluginName` to HandshakeResponse (the optimised pre-calculated-token path), `authPluginName` must be a string. If it is present but non-string, HandshakeResponse throws at construction. Standard connection setup never sets these fields, so this is only relevant to advanced/internal callers.
Source
Thrown at lib/packets/handshake_response.js:34
this.authPluginData2 = handshake.authPluginData2;
this.compress = handshake.compress;
this.clientFlags = handshake.flags;
this.mariadbExtendedClientFlags = handshake.mariadbExtendedClientFlags || 0;
// Accept pre-calculated authToken and authPluginName from caller
// This allows the caller to optimize by using the server's preferred auth method
if (
handshake.authToken !== undefined &&
handshake.authPluginName !== undefined
) {
// Validate types to fail fast with clear errors
if (!Buffer.isBuffer(handshake.authToken)) {
throw new TypeError(
'HandshakeResponse authToken must be a Buffer when provided'
);
}
if (typeof handshake.authPluginName !== 'string') {
throw new TypeError(
'HandshakeResponse authPluginName must be a string when provided'
);
}
this.authToken = handshake.authToken;
this.authPluginName = handshake.authPluginName;
} else {
// Fallback to legacy behavior: calculate mysql_native_password token
// TODO: pre-4.1 auth support
let authToken;
if (this.passwordSha1) {
authToken = auth41.calculateTokenFromPasswordSha(
this.passwordSha1,
this.authPluginData1,
this.authPluginData2
);
} else {
authToken = auth41.calculateToken(
this.password,View on GitHub (pinned to 5ebe8903d6)
Solutions
- Ensure authPluginName is a string: `new HandshakeResponse({ ..., authToken, authPluginName: String(name) })`.
- Omit both fields if you do not need the optimised path.
Example fix
// before
new HandshakeResponse({ ..., authToken, authPluginName: 42 });
// after
new HandshakeResponse({ ..., authToken, authPluginName: 'caching_sha2_password' }); Defensive patterns
Strategy: type-guard
Validate before calling
function buildHandshakeOpts(opts) {
if (opts.authPluginName !== undefined && typeof opts.authPluginName !== 'string') {
throw new TypeError('authPluginName must be a string');
}
return opts;
} Type guard
function isValidAuthPluginName(name) {
return name == null || typeof name === 'string';
} Prevention
- Omit authToken/authPluginName unless you are providing a pre-calculated token.
- Coerce plugin names with String(...) when sourced from dynamic input.
- Keep direct HandshakeResponse use in tests/internal code.
When it happens
Trigger: Constructing HandshakeResponse with `authPluginName` set to a non-string (number, object, Buffer) alongside an `authToken`. Happens in custom handshake code or tests that build the packet manually.
Common situations: A fork or test harness passing the plugin name from an unvalidated source; confusing authPluginName (string) with authToken (Buffer).
Related errors
- HandshakeResponse authToken must be a Buffer when provided
- Unexpected data in AuthMoreData packet received by caching_s
- Unexpected data in AuthMoreData packet received by sha256_pa
- Invalid AuthMoreData packet received by caching_sha2_passwor
- Unexpected data in AuthMoreData packet received by caching_s
AI-assisted analysis of sidorares/node-mysql2@5ebe8903d6 (2026-08-03).
Data as JSON: /data/errors/4b24685f9406ef7a.json.
Report an issue: GitHub.