{"id":"d7f7273013f0470b","repo":"mongodb/node-mongodb-native","slug":"options-keyaltname-must-be-of-type-string-but-w","errorCode":null,"errorMessage":"\"options.keyAltName\" must be of type string, but was of type ${typeof keyAltName}","messagePattern":"\"options\\.keyAltName\" must be of type string, but was of type (.+?)","errorType":"validation","errorClass":"MongoCryptInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/client-side-encryption/client_encryption.ts","lineNumber":785,"sourceCode":"      rangeOptions,\n      stringOptions,\n      textOptions\n    } = options;\n    const contextOptions: ExplicitEncryptionContextOptions = {\n      expressionMode,\n      algorithm\n    };\n    if (keyId) {\n      contextOptions.keyId = keyId.buffer;\n    }\n    if (keyAltName) {\n      if (keyId) {\n        throw new MongoCryptInvalidArgumentError(\n          `\"options\" cannot contain both \"keyId\" and \"keyAltName\"`\n        );\n      }\n      if (typeof keyAltName !== 'string') {\n        throw new MongoCryptInvalidArgumentError(\n          `\"options.keyAltName\" must be of type string, but was of type ${typeof keyAltName}`\n        );\n      }\n\n      contextOptions.keyAltName = serialize({ keyAltName });\n    }\n    if (typeof contentionFactor === 'number' || typeof contentionFactor === 'bigint') {\n      contextOptions.contentionFactor = contentionFactor;\n    }\n    if (typeof queryType === 'string') {\n      contextOptions.queryType = queryType;\n    }\n\n    if (typeof rangeOptions === 'object') {\n      contextOptions.rangeOptions = serialize(rangeOptions);\n    }\n\n    const resolvedStringOptions = stringOptions ?? textOptions;","sourceCodeStart":767,"sourceCodeEnd":803,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/client-side-encryption/client_encryption.ts#L767-L803","documentation":"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.","triggerScenarios":"Calling encrypt(value, { keyAltName: 123, algorithm }) or keyAltName: undefined-but-truthy; passing an object intended as a masterKey in the wrong field.","commonSituations":"TypeScript types bypassed with `as any`; building keyAltName from numeric IDs; confusing keyAltName with keyId (UUID/Binary).","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."],"exampleFix":"// before\nawait ce.encrypt(value, { keyAltName: keyIdUuid, algorithm });\n\n// after\nawait ce.encrypt(value, { keyId: new Binary(keyIdUuid, 4), algorithm });\n// or, if alias:\nawait ce.encrypt(value, { keyAltName: 'myKeyAlias', algorithm });","handlingStrategy":"type-guard","validationCode":"function requireStringKeyAltName(opt) {\n  if ('keyAltName' in opt && typeof opt.keyAltName !== 'string')\n    throw new TypeError('keyAltName must be a string');\n  return opt;\n}","typeGuard":"function isStringKeyAltName(opt: any): opt is { keyAltName: string; keyId?: undefined } {\n  return 'keyAltName' in opt && typeof opt.keyAltName === 'string';\n}","tryCatchPattern":"try { await ce.encrypt(value, opt); }\ncatch (err) {\n  if (err instanceof MongoCryptInvalidArgumentError && /keyAltName\" must be of type string/.test(err.message)) {\n    /* if you have a UUID, switch to keyId; otherwise pass a string alias */\n  } else throw err;\n}","preventionTips":["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."],"tags":["csfle","client-encryption","validation","encryption","typescript"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}