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 when a tags argument is provided but is not an array. Tag sets must be an array of objects (e.g., [{ region: 'us-east' }]). The constructor does accept a single options-shaped object in the tags slot for convenience (treating it as options), but any other non-array value (a string, a single tag object that isn't shaped like options, a number) is rejected. MongoInvalidArgumentError.

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 3366c21a63)

Solutions

  1. Always pass tags as an array of tag-set objects: [{ region: 'us-east' }].
  2. When passing options too, ensure tags is explicitly an array (the single-object-as-options shortcut only applies when no other options arg is given).
  3. In connection strings, repeat readPreferenceTags for multiple tag sets; do not pass a single combined string.
  4. Coerce/validate tags to an array before constructing a ReadPreference.

Example fix

// before
new ReadPreference('secondary', { region: 'us-east' }, { maxStalenessSeconds: 90 });
// after
new ReadPreference('secondary', [{ region: 'us-east' }], { maxStalenessSeconds: 90 });
Defensive patterns

Strategy: type-guard

Validate before calling

if (tags != null && !Array.isArray(tags)) throw new Error('ReadPreference tags must be an array');
new ReadPreference(mode, tags as any[], options);

Type guard

import type { TagSet } from 'mongodb';
function isTagSetArray(v: unknown): v is TagSet[] {
  return Array.isArray(v) && v.every(t => t != null && typeof t === 'object');
}

Prevention

When it happens

Trigger: Calling new ReadPreference('secondary', { region: 'us-east' }) where the single object is interpreted as options (allowed) vs passing a string or malformed value; passing a single tag object alongside an options arg so it isn't auto-detected; passing tags as a comma-separated string.

Common situations: Assuming tags can be a single object when options are also supplied; URI parsing edge cases; passing readPreferenceTags incorrectly; helper code that builds tags dynamically and sometimes yields a non-array.

Related errors


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