{"record":{"id":"b2914ba2d36e8d57","repo":"mongodb/node-mongodb-native","slug":"password-must-be-a-string","errorCode":null,"errorMessage":"Password must be a string","messagePattern":"Password must be a string","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/cmap/auth/scram.ts","lineNumber":223,"sourceCode":"\nfunction parsePayload(payload: Binary) {\n  const payloadStr = ByteUtils.toUTF8(payload.buffer, 0, payload.position, false);\n  const dict: Document = {};\n  const parts = payloadStr.split(',');\n  for (let i = 0; i < parts.length; i++) {\n    const valueParts = (parts[i].match(/^([^=]*)=(.*)$/) ?? []).slice(1);\n    dict[valueParts[0]] = valueParts[1];\n  }\n  return dict;\n}\n\nfunction passwordDigest(username: string, password: string) {\n  if (typeof username !== 'string') {\n    throw new MongoInvalidArgumentError('Username must be a string');\n  }\n\n  if (typeof password !== 'string') {\n    throw new MongoInvalidArgumentError('Password must be a string');\n  }\n\n  if (password.length === 0) {\n    throw new MongoInvalidArgumentError('Password cannot be empty');\n  }\n\n  let nodeCrypto;\n  try {\n    // TODO: NODE-7424 - remove dependency on 'crypto' for SCRAM-SHA-1 authentication\n    // eslint-disable-next-line @typescript-eslint/no-require-imports\n    nodeCrypto = require('crypto');\n  } catch (e) {\n    throw new MongoRuntimeError(\n      'Node.js crypto module is required for SCRAM-SHA-1 authentication',\n      {\n        cause: e\n      }\n    );","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cmap/auth/scram.ts#L205-L241","documentation":"Thrown by passwordDigest (scram.ts:223) when the password passed to it is not a string. The SCRAM-SHA-1 MD5 digest requires a string password; a non-string password (undefined, number, object) cannot be hashed. Raised as MongoInvalidArgumentError. This is an internal type guard; credential parsing normally guarantees a string password before reaching SCRAM.","triggerScenarios":"passwordDigest invoked on the SCRAM-SHA-1 path with a password that is not a string. Reachable only if credentials.password is undefined/null/non-string when SCRAM-SHA-1 runs, bypassing normal credential parsing.","commonSituations":"A driver regression or fork where credentials.password is not coerced to a string. Programmatic MongoCredentials construction with a non-string password. Note: an empty string password throws a separate 'Password cannot be empty' error just below.","solutions":["Ensure password is a non-empty string when constructing credentials","If using the internal API, coerce password to string before it reaches SCRAM","Prefer SCRAM-SHA-256 which routes through saslprep instead of passwordDigest","Report a driver bug if reached via the public API"],"exampleFix":"// before\nconst credentials = { username: 'u', password: undefined, mechanism: 'SCRAM-SHA-1' };\n\n// after\nconst credentials = { username: 'u', password: 'correct-horse', mechanism: 'SCRAM-SHA-1' };","handlingStrategy":"type-guard","validationCode":"if (typeof clientOptions.auth?.password !== 'string') {\n  throw new TypeError('auth.password must be a string');\n}","typeGuard":"function isStringPassword(auth: { password?: unknown }): auth is { password: string } {\n  return typeof auth.password === 'string' && auth.password.length > 0;\n}","tryCatchPattern":"try {\n  await client.connect();\n} catch (err) {\n  if (err instanceof MongoInvalidArgumentError && /Password must be a string/.test(err.message)) {\n    // supply a valid string password and retry\n  } else throw err;\n}","preventionTips":["Always pass string credentials via the public MongoClient options","Validate auth.password is a non-empty string at config-load time","Prefer SCRAM-SHA-256, which routes through saslprep rather than passwordDigest"],"tags":["scram","types","internal","authentication"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}