mongodb/node-mongodb-native · error · MongoParseError

ReadConcern must be an object, got

Error message

ReadConcern must be an object, got ${JSON.stringify(value)}

What it means

The `readConcern` option must be either a ReadConcern instance or a record containing a `level` field; the transform at src/connection_string.ts:992 checks `value instanceof ReadConcern || isRecord(value, ['level'])`. Anything else — a string, number, array — throws MongoParseError at src/connection_string.ts:996. Use the separate `readConcernLevel` option to pass a bare level string.

Solutions

  1. Use `readConcernLevel: 'majority'` for a bare string level.
  2. Or pass an object: `readConcern: { level: 'majority' }`.
  3. Or construct `new ReadConcern('majority')` and pass that instance.

Example fix

// before
new MongoClient(uri, { readConcern: 'majority' });

// after
new MongoClient(uri, { readConcernLevel: 'majority' });
Defensive patterns

Strategy: type-guard

Validate before calling

import { ReadConcern } from 'mongodb';
function isReadConcernLike(v: unknown): boolean {
  return v instanceof ReadConcern || (!!v && typeof v === 'object' && 'level' in v);
}
if (opts.readConcern != null && !isReadConcernLike(opts.readConcern)) {
  throw new Error('readConcern must be { level } or a ReadConcern instance');
}

Type guard

function isReadConcernLike(v: unknown): v is { level: string } { return !!v && typeof v === 'object' && 'level' in v; }

Try / catch

try { client = new MongoClient(uri, opts); } catch (e) { if (e instanceof MongoParseError && /ReadConcern/.test(e.message)) { const lvl = (opts as any).readConcern; delete (opts as any).readConcern; opts.readConcernLevel = String(lvl); client = new MongoClient(uri, opts); } else throw e; }

Prevention

When it happens

Trigger: Passing `readConcern: 'majority'` (string), `readConcern: 1`, `readConcern: ['local']`, or `readConcern: { consistency: 'majority' }` (wrong key).

Common situations: Treating readConcern like readPreference (which does accept a string); copying the level string into the wrong option; ODM wrappers that pass through user strings unchanged.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/30e9801cb0750d03. Report an issue: GitHub.

Appendix: source

Thrown at src/connection_string.ts:996

  proxyPassword: {
    type: 'string'
  },
  proxyPort: {
    type: 'uint'
  },
  proxyUsername: {
    type: 'string'
  },
  raw: {
    default: false,
    type: 'boolean'
  },
  readConcern: {
    transform({ values: [value], options }) {
      if (value instanceof ReadConcern || isRecord(value, ['level'] as const)) {
        return ReadConcern.fromOptions({ ...options.readConcern, ...value });
      }
      throw new MongoParseError(`ReadConcern must be an object, got ${JSON.stringify(value)}`);
    }
  },
  readConcernLevel: {
    target: 'readConcern',
    transform({ values: [level], options }) {
      return ReadConcern.fromOptions({
        ...options.readConcern,
        level: level as ReadConcernLevel
      });
    }
  },
  readPreference: {
    default: ReadPreference.primary,
    transform({ values: [value], options }) {
      if (value instanceof ReadPreference) {
        return ReadPreference.fromOptions({
          readPreference: { ...options.readPreference, ...value },
          ...value

View on GitHub (pinned to dce7939f86)