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

  1. Ensure options.keyAltName is a JavaScript string (the alternate name the data key was created with).
  2. If the value comes from dynamic input, coerce/validate: if (typeof keyAltName !== 'string') throw ... before calling encrypt.
  3. 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

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


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)