mongodb/node-mongodb-native · error · MongoCryptInvalidArgumentError

Option "keyAltNames" must be an array of strings, but item a

Error message

Option "keyAltNames" must be an array of strings, but item at index ${i} was of type ${typeof keyAltName}

What it means

Thrown by ClientEncryption.createDataKey (MongoCryptInvalidArgumentError) when options.keyAltNames is an array but one of its elements is not a string. The message names the offending index so you can locate the bad element. Each alias is serialized to BSON by key, so non-string items break serialization.

Source

Thrown at src/client-side-encryption/client_encryption.ts:211

   *   keyAltNames: [ 'mySpecialKey' ]
   * });
   * ```
   */
  async createDataKey(
    provider: ClientEncryptionDataKeyProvider,
    options: ClientEncryptionCreateDataKeyProviderOptions = {}
  ): Promise<UUID> {
    if (options.keyAltNames && !Array.isArray(options.keyAltNames)) {
      throw new MongoCryptInvalidArgumentError(
        `Option "keyAltNames" must be an array of strings, but was of type ${typeof options.keyAltNames}.`
      );
    }

    let keyAltNames = undefined;
    if (options.keyAltNames && options.keyAltNames.length > 0) {
      keyAltNames = options.keyAltNames.map((keyAltName, i) => {
        if (typeof keyAltName !== 'string') {
          throw new MongoCryptInvalidArgumentError(
            `Option "keyAltNames" must be an array of strings, but item at index ${i} was of type ${typeof keyAltName}`
          );
        }

        return serialize({ keyAltName });
      });
    }

    let keyMaterial = undefined;
    if (options.keyMaterial) {
      keyMaterial = serialize({ keyMaterial: options.keyMaterial });
    }

    const dataKeyBson = serialize({
      provider,
      ...options.masterKey
    });

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Sanitize the array so every element is a string: keyAltNames.filter(x => typeof x === 'string').
  2. Fix the source of the offending element so only strings reach the option.
  3. Add a unit test that asserts all elements are strings before createDataKey is called.

Example fix

// before
await ce.createDataKey('local', { keyAltNames: ['myKey', 123] });

// after
await ce.createDataKey('local', { keyAltNames: ['myKey', '123'] });
Defensive patterns

Strategy: validation

Validate before calling

function sanitizeKeyAltNames(opt) {
  if (Array.isArray(opt.keyAltNames))
    opt.keyAltNames = opt.keyAltNames.filter(x => typeof x === 'string');
  return opt;
}

Type guard

function isStringArray(v: unknown): v is string[] {
  return Array.isArray(v) && v.every(x => typeof x === 'string');
}

Try / catch

try { await ce.createDataKey('local', opt); }
catch (err) {
  if (err instanceof MongoCryptInvalidArgumentError && /item at index/.test(err.message)) {
    /* coerce/filter non-strings out of keyAltNames */
  } else throw err;
}

Prevention

When it happens

Trigger: Calling createDataKey with keyAltNames: ['valid', 42] or keyAltNames: [null, 'x']; mixing types when the array is built dynamically.

Common situations: Building keyAltNames from user input or a config that permits non-strings; deserialized JSON containing numbers; refactoring that leaves a placeholder null.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/61d7691c046638bf.json. Report an issue: GitHub.