mongodb/node-mongodb-native · error · MongoInvalidArgumentError

ReadPreference tags must be an array

Error message

ReadPreference tags must be an array

What it means

Thrown by the ReadPreference constructor (src/read_preference.ts:92) when the second argument is a non-array, non-object-or-an-object-that-should-be-options. If the constructor sees a truthy tags argument that is not an array (and not a plain object interpreted as options), it raises MongoInvalidArgumentError. Tags must be a TagSet[] (array of objects).

Solutions

  1. Pass tags as an array: new ReadPreference('secondary', [{ region: 'us' }]).
  2. If you meant to pass options, omit tags or pass undefined as the second argument.

Example fix

// before
const rp = new ReadPreference('secondary', { region: 'us' });
// after
const rp = new ReadPreference('secondary', [{ region: 'us' }]);
Defensive patterns

Strategy: validation

Validate before calling

function buildRP(mode, tags) {
  const tagArr = tags == null ? undefined : Array.isArray(tags) ? tags : [tags];
  return new ReadPreference(mode, tagArr);
}

Type guard

function isTagSetArray(v): v is Array<Record<string,string>> {
  return Array.isArray(v) && v.every(t => t != null && typeof t === 'object');
}

Try / catch

try {
  new ReadPreference('secondary', tags);
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /tags must be an array/.test(e.message)) {
    // coerce to array and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling new ReadPreference('secondary', { region: 'us' }) intending a single tag set — the driver expects an array of tag-set objects. Also new ReadPreference('secondary', 'us') or new ReadPreference('secondary', 5).

Common situations: Confusing the tags argument (array of tag sets) with a single tag-set object or with the options object.

Related errors


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

Appendix: source

Thrown at src/read_preference.ts:92

  public static primaryPreferred = new ReadPreference(ReadPreferenceMode.primaryPreferred);
  public static secondary = new ReadPreference(ReadPreferenceMode.secondary);
  public static secondaryPreferred = new ReadPreference(ReadPreferenceMode.secondaryPreferred);
  public static nearest = new ReadPreference(ReadPreferenceMode.nearest);

  /**
   * @param mode - A string describing the read preference mode (primary|primaryPreferred|secondary|secondaryPreferred|nearest)
   * @param tags - A tag set used to target reads to members with the specified tag(s). tagSet is not available if using read preference mode primary.
   * @param options - Additional read preference options
   */
  constructor(mode: ReadPreferenceMode, tags?: TagSet[], options?: ReadPreferenceOptions) {
    if (!ReadPreference.isValid(mode)) {
      throw new MongoInvalidArgumentError(`Invalid read preference mode ${JSON.stringify(mode)}`);
    }
    if (options == null && typeof tags === 'object' && !Array.isArray(tags)) {
      options = tags;
      tags = undefined;
    } else if (tags && !Array.isArray(tags)) {
      throw new MongoInvalidArgumentError('ReadPreference tags must be an array');
    }

    this.mode = mode;
    this.tags = tags;
    this.hedge = options?.hedge;
    this.maxStalenessSeconds = undefined;

    options = options ?? {};
    if (options.maxStalenessSeconds != null) {
      if (options.maxStalenessSeconds <= 0) {
        throw new MongoInvalidArgumentError('maxStalenessSeconds must be a positive integer');
      }

      this.maxStalenessSeconds = options.maxStalenessSeconds;
    }

    if (this.mode === ReadPreference.PRIMARY) {
      if (this.tags && Array.isArray(this.tags) && this.tags.length > 0) {

View on GitHub (pinned to dce7939f86)