mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Username must be a string
Error message
Username must be a string
What it means
Thrown by passwordDigest() (scram.ts:219) as a MongoInvalidArgumentError when the username passed in is not a string. passwordDigest builds the MD5 of 'username:mongo:password' for SCRAM-SHA-1, so a non-string username (number, object, undefined) cannot be hashed. This guards an internal helper invoked during SCRAM-SHA-1 auth.
Source
Thrown at src/cmap/auth/scram.ts:219
};
await connection.command(ns(`${db}.$cmd`), retrySaslContinueCmd, undefined);
}
function parsePayload(payload: Binary) {
const payloadStr = ByteUtils.toUTF8(payload.buffer, 0, payload.position, false);
const dict: Document = {};
const parts = payloadStr.split(',');
for (let i = 0; i < parts.length; i++) {
const valueParts = (parts[i].match(/^([^=]*)=(.*)$/) ?? []).slice(1);
dict[valueParts[0]] = valueParts[1];
}
return dict;
}
function passwordDigest(username: string, password: string) {
if (typeof username !== 'string') {
throw new MongoInvalidArgumentError('Username must be a string');
}
if (typeof password !== 'string') {
throw new MongoInvalidArgumentError('Password must be a string');
}
if (password.length === 0) {
throw new MongoInvalidArgumentError('Password cannot be empty');
}
let nodeCrypto;
try {
// TODO: NODE-7424 - remove dependency on 'crypto' for SCRAM-SHA-1 authentication
// eslint-disable-next-line @typescript-eslint/no-require-imports
nodeCrypto = require('crypto');
} catch (e) {
throw new MongoRuntimeError(
'Node.js crypto module is required for SCRAM-SHA-1 authentication',View on GitHub (pinned to 3366c21a63)
Solutions
- Ensure the username is a string - coerce with String(username) if loading from typed config
- Validate credentials shape before passing to MongoClient
- Use SCRAM-SHA-256 (default in modern MongoDB) where possible
Example fix
// before const username = config.dbUser; // number 12345 // after const username = String(config.dbUser);
Defensive patterns
Strategy: validation
Validate before calling
function assertStringUsername(username: unknown): asserts username is string {
if (typeof username !== 'string') throw new TypeError('username must be a string');
}
assertStringUsername(config.dbUser); Type guard
function isStringUsername(u: unknown): u is string {
return typeof u === 'string';
} Prevention
- Coerce config values to string before passing to MongoClient
- Validate credentials shape at app startup
- Use TypeScript types strictly; avoid 'any' for credential fields
When it happens
Trigger: Credentials object whose username field is not a string (e.g. a number parsed from config without coercion, or undefined leaking through a loosely-typed credentials builder). Reachable if a MongoCredentials is constructed bypassing its normal validation.
Common situations: Numeric usernames in config systems that did not stringify; a credentials provider returning an object whose .username is undefined after a failed lookup; TS type-safety bypassed at runtime.
Related errors
- Password must be a string
- Password cannot be empty
- Username required for mechanism '${this.mechanism}'
- AuthContext must provide credentials.
- AuthContext must provide credentials.
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/c3f2effd2fe1d3dd.json.
Report an issue: GitHub.