{"id":"d3ac4c0151e061ee","repo":"mongodb/node-mongodb-native","slug":"readpreference-tags-must-be-an-array","errorCode":null,"errorMessage":"ReadPreference tags must be an array","messagePattern":"ReadPreference tags must be an array","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/read_preference.ts","lineNumber":92,"sourceCode":"  public static primaryPreferred = new ReadPreference(ReadPreferenceMode.primaryPreferred);\n  public static secondary = new ReadPreference(ReadPreferenceMode.secondary);\n  public static secondaryPreferred = new ReadPreference(ReadPreferenceMode.secondaryPreferred);\n  public static nearest = new ReadPreference(ReadPreferenceMode.nearest);\n\n  /**\n   * @param mode - A string describing the read preference mode (primary|primaryPreferred|secondary|secondaryPreferred|nearest)\n   * @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.\n   * @param options - Additional read preference options\n   */\n  constructor(mode: ReadPreferenceMode, tags?: TagSet[], options?: ReadPreferenceOptions) {\n    if (!ReadPreference.isValid(mode)) {\n      throw new MongoInvalidArgumentError(`Invalid read preference mode ${JSON.stringify(mode)}`);\n    }\n    if (options == null && typeof tags === 'object' && !Array.isArray(tags)) {\n      options = tags;\n      tags = undefined;\n    } else if (tags && !Array.isArray(tags)) {\n      throw new MongoInvalidArgumentError('ReadPreference tags must be an array');\n    }\n\n    this.mode = mode;\n    this.tags = tags;\n    this.hedge = options?.hedge;\n    this.maxStalenessSeconds = undefined;\n\n    options = options ?? {};\n    if (options.maxStalenessSeconds != null) {\n      if (options.maxStalenessSeconds <= 0) {\n        throw new MongoInvalidArgumentError('maxStalenessSeconds must be a positive integer');\n      }\n\n      this.maxStalenessSeconds = options.maxStalenessSeconds;\n    }\n\n    if (this.mode === ReadPreference.PRIMARY) {\n      if (this.tags && Array.isArray(this.tags) && this.tags.length > 0) {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/read_preference.ts#L74-L110","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Always pass tags as an array of tag-set objects: [{ region: 'us-east' }].","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).","In connection strings, repeat readPreferenceTags for multiple tag sets; do not pass a single combined string.","Coerce/validate tags to an array before constructing a ReadPreference."],"exampleFix":"// before\nnew ReadPreference('secondary', { region: 'us-east' }, { maxStalenessSeconds: 90 });\n// after\nnew ReadPreference('secondary', [{ region: 'us-east' }], { maxStalenessSeconds: 90 });","handlingStrategy":"type-guard","validationCode":"if (tags != null && !Array.isArray(tags)) throw new Error('ReadPreference tags must be an array');\nnew ReadPreference(mode, tags as any[], options);","typeGuard":"import type { TagSet } from 'mongodb';\nfunction isTagSetArray(v: unknown): v is TagSet[] {\n  return Array.isArray(v) && v.every(t => t != null && typeof t === 'object');\n}","tryCatchPattern":null,"preventionTips":["Always pass tags as an array of tag-set objects.","When also passing options, set tags explicitly to an array (the object shortcut won't apply).","In URIs, use repeated readPreferenceTags entries."],"tags":["read-preference","tags","validation","argument-error"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}