mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Option "readPreference" must be a ReadPreference instance
Error message
Option "readPreference" must be a ReadPreference instance
What it means
Thrown by getReadPreference() when the readPreference option is neither a string nor a ReadPreference instance. The function accepts a ReadPreference instance or a string (which it converts via ReadPreference.fromString); anything else (number, object, null after coalescing) is invalid. Surfaced as MongoInvalidArgumentError. This is a direct user-facing validation of the readPreference option.
Source
Thrown at src/cmap/wire_protocol/shared.ts:23
import type { ServerDescription } from '../../sdam/server_description';
import type { Topology } from '../../sdam/topology';
import { TopologyDescription } from '../../sdam/topology_description';
import type { Connection } from '../connection';
export interface ReadPreferenceOption {
readPreference?: ReadPreferenceLike;
}
export function getReadPreference(options?: ReadPreferenceOption): ReadPreference {
// Default to command version of the readPreference.
let readPreference = options?.readPreference ?? ReadPreference.primary;
if (typeof readPreference === 'string') {
readPreference = ReadPreference.fromString(readPreference);
}
if (!(readPreference instanceof ReadPreference)) {
throw new MongoInvalidArgumentError(
'Option "readPreference" must be a ReadPreference instance'
);
}
return readPreference;
}
export function isSharded(topologyOrServer?: Topology | Server | Connection): boolean {
if (topologyOrServer == null) {
return false;
}
if (topologyOrServer.description && topologyOrServer.description.type === ServerType.Mongos) {
return true;
}
// NOTE: This is incredibly inefficient, and should be removed once command construction
// happens based on `Server` not `Topology`.View on GitHub (pinned to 3366c21a63)
Solutions
- Pass readPreference as a string: 'primary' | 'primaryPreferred' | 'secondary' | 'secondaryPreferred' | 'nearest'.
- Or construct a ReadPreference instance: ReadPreference.fromString('secondary') or new ReadPreference('secondary', tags).
- Avoid plain objects like { mode: 'secondary' }; the driver does not accept them.
Example fix
// before - plain object is not accepted
collection.find({}, { readPreference: { mode: 'secondary' } });
// after - use a string or a ReadPreference instance
import { ReadPreference } from 'mongodb';
collection.find({}, { readPreference: 'secondary' });
// or with tags
collection.find({}, { readPreference: new ReadPreference('secondary', [{ region: 'us-east' }]) }); Defensive patterns
Strategy: type-guard
Validate before calling
import { ReadPreference } from 'mongodb';
const VALID_MODES = new Set(['primary','primaryPreferred','secondary','secondaryPreferred','nearest']);
function normalizeReadPreference(rp) {
if (typeof rp === 'string') { if (!VALID_MODES.has(rp)) throw new Error(`Invalid readPreference string: ${rp}`); return rp; }
if (rp instanceof ReadPreference) return rp;
throw new Error('readPreference must be a string or ReadPreference instance');
}
// usage
collection.find({}, { readPreference: normalizeReadPreference(options.readPreference) }); Type guard
import { ReadPreference } from 'mongodb';
function isReadPreferenceLike(rp): rp is string | ReadPreference {
return typeof rp === 'string' || rp instanceof ReadPreference;
}
// usage
if (!isReadPreferenceLike(opts.readPreference)) throw new TypeError('Invalid readPreference'); Try / catch
try {
await collection.find({}, { readPreference }).toArray();
} catch (err) {
if (err instanceof MongoInvalidArgumentError && /readPreference" must be a ReadPreference instance/.test(err.message)) {
// pass a string ('secondary') or a ReadPreference instance instead of a plain object
}
throw err;
} Prevention
- Pass readPreference as one of the string modes or a ReadPreference instance.
- Never pass a plain object { mode, tags }; construct ReadPreference instead.
- Centralize readPreference normalization in a helper to avoid ad-hoc values.
When it happens
Trigger: An operation or MongoClient is given options.readPreference set to an invalid value such as an object that is not a ReadPreference instance, a number, or a malformed value. Passing { mode: 'secondary' } (a plain object) instead of a ReadPreference instance or the string 'secondary' triggers it.
Common situations: Passing a plain object { mode, tags } instead of ReadPreference.construct(). Passing a typo or wrong-type value (e.g. a number). Library/framework that forwards a non-normalized readPreference into a driver call.
Related errors
- Primary read preference cannot be combined with hedge
- Invalid read preference: ${r}
- Missing required option `keyVaultNamespace`
- Option "keyAltNames" must be an array of strings, but was of
- Option "keyAltNames" must be an array of strings, but item a
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/8ea69d14e72e7000.json.
Report an issue: GitHub.