sidorares/node-mysql2 · error · Error
"user" connection config property must be a string
Error message
"user" connection config property must be a string
What it means
ChangeUser.toPacket (lib/packets/change_user.js:84-87) serializes a COM_CHANGE_USER packet and validates that user is a string before writing it null-terminated. A non-string user (number, undefined-after-coalesce, object) would corrupt the packet framing, so the driver throws before serialization.
Solutions
- Coerce explicitly: String(opts.user).
- Validate typeof opts.user === 'string' before calling changeUser.
- Fix the upstream source so user is always a string.
Example fix
// before
connection.changeUser({ user: req.body.userId }); // number
// after
connection.changeUser({ user: String(req.body.userId) }); Defensive patterns
Strategy: validation
Validate before calling
function assertChangeUserOpts(opts) {
if (typeof opts.user !== 'string') throw new TypeError('changeUser: user must be string');
} Type guard
const isUserString = (opts) => typeof (opts && opts.user) === 'string';
Prevention
- Always coerce user to String at the boundary that reads config/env.
- Type the changeUser options argument strictly.
When it happens
Trigger: Calling connection.changeUser({ user: 123 }) or passing a config object whose user field is undefined/number; reusing a request body directly as changeUser options where user came in as a non-string.
Common situations: Loose env coercion (user: Number(process.env.DB_USER)); passing the entire request.user object instead of request.user.id; defaulting user with || from a missing value yielding a non-string.
Related errors
- "database" connection config property must be a string
- Bind parameters must not contain undefined
- HandshakeResponse authPluginName must be a string when…
- HandshakeResponse authToken must be a Buffer when provided
- SSL profile must be an object, instead it's a
AI-assisted analysis of sidorares/node-mysql2@8b1f829d37 (2026-08-11).
Data as JSON: /api/errors/bcb741c0163f1cff.
Report an issue: GitHub.
Appendix: source
Thrown at lib/packets/change_user.js:86
connectAttributes[attrNames[k]],
encoding
);
}
packet.writeLengthCodedNumber(keysLength);
for (let k = 0; k < attrNames.length; ++k) {
packet.writeLengthCodedString(attrNames[k], encoding);
packet.writeLengthCodedString(
connectAttributes[attrNames[k]],
encoding
);
}
}
return packet;
}
toPacket() {
if (typeof this.user !== 'string') {
throw new Error('"user" connection config property must be a string');
}
if (typeof this.database !== 'string') {
throw new Error('"database" connection config property must be a string');
}
// dry run: calculate resulting packet length
const p = this.serializeToBuffer(Packet.MockBuffer());
return this.serializeToBuffer(Buffer.allocUnsafe(p.offset));
}
}
module.exports = ChangeUser;
View on GitHub (pinned to 8b1f829d37)