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 by ClientEncryption.encrypt (MongoCryptInvalidArgumentError) when options.keyAltName is provided but is not a string. keyAltName is serialized as a BSON string key, so a non-string value (number, object, null) is rejected before reaching libmongocrypt.
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 3366c21a63)
Solutions
- Ensure keyAltName is a string alias previously registered via createDataKey.
- If you have a UUID, use keyId (Binary) instead of keyAltName.
- Add a runtime type check `typeof keyAltName === 'string'` before calling encrypt when values come from untyped sources.
Example fix
// before
await ce.encrypt(value, { keyAltName: keyIdUuid, algorithm });
// after
await ce.encrypt(value, { keyId: new Binary(keyIdUuid, 4), algorithm });
// or, if alias:
await ce.encrypt(value, { keyAltName: 'myKeyAlias', algorithm }); Defensive patterns
Strategy: type-guard
Validate before calling
function requireStringKeyAltName(opt) {
if ('keyAltName' in opt && typeof opt.keyAltName !== 'string')
throw new TypeError('keyAltName must be a string');
return opt;
} Type guard
function isStringKeyAltName(opt: any): opt is { keyAltName: string; keyId?: undefined } {
return 'keyAltName' in opt && typeof opt.keyAltName === 'string';
} Try / catch
try { await ce.encrypt(value, opt); }
catch (err) {
if (err instanceof MongoCryptInvalidArgumentError && /keyAltName" must be of type string/.test(err.message)) {
/* if you have a UUID, switch to keyId; otherwise pass a string alias */
} else throw err;
} Prevention
- Type keyAltName as string in your CSFLE option types.
- Avoid `as any` casts when assembling encrypt options.
- Use keyId (Binary) for UUIDs; reserve keyAltName for human-readable aliases.
When it happens
Trigger: Calling encrypt(value, { keyAltName: 123, algorithm }) or keyAltName: undefined-but-truthy; passing an object intended as a masterKey in the wrong field.
Common situations: TypeScript types bypassed with `as any`; building keyAltName from numeric IDs; confusing keyAltName with keyId (UUID/Binary).
Related errors
- Option "keyAltNames" must be an array of strings, but was of
- Option "keyAltNames" must be an array of strings, but item a
- "options" cannot contain both "keyId" and "keyAltName"
- Missing required option `keyVaultNamespace`
- Cannot set both proxyOptions and kmsConnectCallback
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/d7f7273013f0470b.json.
Report an issue: GitHub.