mongodb/node-mongodb-native · error · MongoParseError

${name} must be an object

Error message

${name} must be an object

What it means

Thrown by setOption (connection_string.ts:616-618) for options whose descriptor type is 'record' (e.g. autoEncryption, driverInfo, fieldsAsRaw) when the provided value is not a plain object. The isRecord helper rejects arrays, primitives, null, and non-plain objects because record options are always key-value maps.

Source

Thrown at src/connection_string.ts:617

      break;
    case 'int':
      mongoOptions[name] = getIntFromOptions(name, values[0]);
      break;
    case 'uint':
      mongoOptions[name] = getUIntFromOptions(name, values[0]);
      break;
    case 'string':
      if (values[0] == null) {
        break;
      }
      // The value should always be a string here, but since the array is typed as unknown
      // there still needs to be an explicit cast.
      // eslint-disable-next-line @typescript-eslint/no-base-to-string
      mongoOptions[name] = String(values[0]);
      break;
    case 'record':
      if (!isRecord(values[0])) {
        throw new MongoParseError(`${name} must be an object`);
      }
      mongoOptions[name] = values[0];
      break;
    case 'any':
      mongoOptions[name] = values[0];
      break;
    default: {
      if (!transform) {
        throw new MongoParseError('Descriptors missing a type must define a transform');
      }
      const transformValue = transform({ name, options: mongoOptions, values });
      mongoOptions[name] = transformValue;
      break;
    }
  }
}

interface OptionDescriptor {

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Pass a plain object literal (e.g. { autoEncryption: { keyVaultNamespace: 'enc.kv', kmsProviders: {...} } }).
  2. If the value comes from a string source, JSON.parse it before passing.
  3. For fieldsAsRaw / driverInfo, ensure the value is { } with string keys.

Example fix

// before
const c = new MongoClient(uri, { autoEncryption: process.env.AUTO_ENC }); // string!
// after
const c = new MongoClient(uri, { autoEncryption: JSON.parse(process.env.AUTO_ENC) });
Defensive patterns

Strategy: type-guard

Validate before calling

for (const k of ['autoEncryption', 'driverInfo', 'fieldsAsRaw']) {
  if (k in opts && (typeof opts[k] !== 'object' || opts[k] === null || Array.isArray(opts[k]))) {
    throw new Error(`Option ${k} must be a plain object`);
  }
}

Type guard

import type { MongoClientOptions } from 'mongodb';
function isPlainObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v) && Object.getPrototypeOf(v) === Object.prototype;
}
function assertRecordOptions(opts: Partial<MongoClientOptions>) {
  for (const k of ['autoEncryption', 'driverInfo', 'fieldsAsRaw'] as const) {
    if (k in opts && !isPlainObject(opts[k])) throw new Error(`${k} must be an object`);
  }
}

Prevention

When it happens

Trigger: Options { autoEncryption: 'enabled' } (string instead of object), { driverInfo: ['x'] } (array), or passing a JSON string instead of a parsed object.

Common situations: Reading config from a string source (env var, file) and forgetting to JSON.parse it; passing a boolean flag where a configuration object is expected; using an array for fieldsAsRaw.

Related errors


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