mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Invalid read preference: ${readPreference}

Error message

Invalid read preference: ${readPreference}

What it means

Thrown by cursor.withReadPreference(readPreference) when the argument is neither a ReadPreference instance nor a string. ReadPreferenceLike is the union of those two; any other type (number, object without the right shape, symbol) is rejected.

Source

Thrown at src/cursor/abstract_cursor.ts:760

      this.transform = transform;
    }

    return this as unknown as AbstractCursor<T>;
  }

  /**
   * Set the ReadPreference for the cursor.
   *
   * @param readPreference - The new read preference for the cursor.
   */
  withReadPreference(readPreference: ReadPreferenceLike): this {
    this.throwIfInitialized();
    if (readPreference instanceof ReadPreference) {
      this.cursorOptions.readPreference = readPreference;
    } else if (typeof readPreference === 'string') {
      this.cursorOptions.readPreference = ReadPreference.fromString(readPreference);
    } else {
      throw new MongoInvalidArgumentError(`Invalid read preference: ${readPreference}`);
    }

    return this;
  }

  /**
   * Set the ReadPreference for the cursor.
   *
   * @param readPreference - The new read preference for the cursor.
   */
  withReadConcern(readConcern: ReadConcernLike): this {
    this.throwIfInitialized();
    const resolvedReadConcern = ReadConcern.fromOptions({ readConcern });
    if (resolvedReadConcern) {
      this.cursorOptions.readConcern = resolvedReadConcern;
    }

    return this;

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Pass a string: withReadPreference('secondary').
  2. Pass a ReadPreference instance: withReadPreference(new ReadPreference('secondary', [{ region: 'us-east' }])).
  3. Set readPreference at the find()/aggregate() options level instead of mutating the cursor.

Example fix

// before
cursor.withReadPreference({ mode: 'secondary' });
// after
cursor.withReadPreference('secondary');
Defensive patterns

Strategy: type-guard

Validate before calling

import { ReadPreference } from 'mongodb';
function isReadPrefLike(v) { return v instanceof ReadPreference || typeof v === 'string'; }

Type guard

import type { ReadPreferenceLike } from 'mongodb';
function isReadPreferenceLike(v): v is ReadPreferenceLike {
  return v instanceof ReadPreference || typeof v === 'string';
}

Prevention

When it happens

Trigger: Calling withReadPreference({ mode: 'primary' }) (plain object instead of instance), withReadPreference(2), withReadPreference(null), or withReadPreference(['secondary']). The string branch only accepts values that ReadPreference.fromString can parse.

Common situations: Passing a JSON-parsed config object that looks like a ReadPreference but is not an instance; passing a tag-set object directly; confusion between readPreference (the option) and ReadPreference (the class).

Related errors


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