mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Invalid read preference

Error message

Invalid read preference: ${readPreference}

What it means

Thrown as a MongoInvalidArgumentError from withReadPreference() when the argument is neither a ReadPreference instance nor a string. The method accepts those two shapes (a string is parsed via ReadPreference.fromString) and rejects everything else (numbers, plain objects without the mode, null) so an invalid preference does not silently fall back to primary. It runs after throwIfInitialized(), so it also cannot be changed once iteration has started.

Solutions

  1. Pass a string mode: cursor.withReadPreference('secondary').
  2. Or pass a ReadPreference instance: cursor.withReadPreference(new ReadPreference('nearest')).
  3. Set readPreference in the cursor options object at construction time using a recognized string/instance.

Example fix

// before: plain object is not accepted
cursor.withReadPreference({ mode: 'nearest' });

// after: use a string or a ReadPreference instance
cursor.withReadPreference('nearest');
// or
cursor.withReadPreference(new ReadPreference('nearest', [{ tag: 'region', value: 'eu' }]));
Defensive patterns

Strategy: type-guard

Validate before calling

import { ReadPreference } from 'mongodb';
if (typeof rp !== 'string' && !(rp instanceof ReadPreference)) {
  throw new TypeError('readPreference must be a string or ReadPreference instance');
}

Type guard

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

Prevention

When it happens

Trigger: cursor.withReadPreference({ mode: 'nearest' }) (plain object instead of ReadPreference instance); cursor.withReadPreference(2); cursor.withReadPreference(null).

Common situations: Passing a raw options object shaped like a read preference; deserializing a preference from JSON into a plain object; confusing the readPreference string ('secondary') with a numeric enum from another driver.

Related errors


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

Appendix: 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 dce7939f86)