mongodb/node-mongodb-native · error · MongoCryptInvalidArgumentError
"options.keyAltName" must be of type string, but was of type
Error message
"options.keyAltName" must be of type string, but was of type ${typeof keyAltName} What it means
Thrown during CSFLE explicit encryption when options.keyAltName is present but is not a string (e.g. a number, object, or Binary). libmongocrypt serializes keyAltName as a BSON string, so only a JS string is accepted. It is a MongoCryptInvalidArgumentError raised inside _encrypt before the encryption context is created.
Solutions
- Ensure options.keyAltName is a JavaScript string (the alternate name the data key was created with).
- If the value comes from dynamic input, coerce/validate: if (typeof keyAltName !== 'string') throw ... before calling encrypt.
- Use createDataKey with keyAltNames: ['myName'] first, then pass that exact string to encrypt.
Example fix
// before
await clientEncryption.encrypt(value, {
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-DETERMINISTIC',
keyAltName: keyDocument._id // Binary, not a string
});
// after
await clientEncryption.encrypt(value, {
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-DETERMINISTIC',
keyAltName: 'customerKey' // the string alt name
}); Defensive patterns
Strategy: type-guard
Validate before calling
if (options.keyAltName != null && typeof options.keyAltName !== 'string') {
throw new TypeError('options.keyAltName must be a string');
} Type guard
function isKeyAltName(v: unknown): v is string {
return typeof v === 'string' && v.length > 0;
} Prevention
- Type encrypt options with the driver's ClientEncryptionEncryptOptions so the compiler rejects non-string keyAltName.
- Do not store key alt names as numbers/objects in config.
When it happens
Trigger: Passing keyAltName as a non-string such as clientEncryption.encrypt(value, { keyAltName: 123, algorithm }) or keyAltName: someBinary; or reading keyAltName from a loosely-typed config/JSON source without coercing.
Common situations: Storing key alt names as numeric IDs in a config file and forwarding them unmodified; passing the whole data key document (_id Binary) into keyAltName instead of its string alt name; TypeScript any-typed option builders that bypass compile-time checks.
Related errors
- "options" cannot contain both "keyId" and "keyAltName"
- Argument "docs" must be an array of documents
- Argument "operations" must be an array of documents
- Argument "pipeline" must be an array of aggregation stages
- Collection.insertMany() cannot be called with an array that…
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/d7f7273013f0470b.
Report an issue: GitHub.
Appendix: source
Thrown at src/client-side-encryption/client_encryption.ts:785
rangeOptions,
stringOptions,
textOptions
} = options;
const contextOptions: ExplicitEncryptionContextOptions = {
expressionMode,
algorithm
};
if (keyId) {
contextOptions.keyId = keyId.buffer;
}
if (keyAltName) {
if (keyId) {
throw new MongoCryptInvalidArgumentError(
`"options" cannot contain both "keyId" and "keyAltName"`
);
}
if (typeof keyAltName !== 'string') {
throw new MongoCryptInvalidArgumentError(
`"options.keyAltName" must be of type string, but was of type ${typeof keyAltName}`
);
}
contextOptions.keyAltName = serialize({ keyAltName });
}
if (typeof contentionFactor === 'number' || typeof contentionFactor === 'bigint') {
contextOptions.contentionFactor = contentionFactor;
}
if (typeof queryType === 'string') {
contextOptions.queryType = queryType;
}
if (typeof rangeOptions === 'object') {
contextOptions.rangeOptions = serialize(rangeOptions);
}
const resolvedStringOptions = stringOptions ?? textOptions;View on GitHub (pinned to dce7939f86)