mongodb/node-mongodb-native · error · MongoInvalidArgumentError

URI option " " cannot appear more than once in the…

Error message

URI option "${key}" cannot appear more than once in the connection string

What it means

With the exception of readPreferenceTags, each URI query parameter may appear at most once. The driver collects all values per key; if a non-readPreferenceTags key has more than one value, it throws MongoInvalidArgumentError to avoid silent ambiguity about which value wins.

Solutions

  1. Search the URI for the duplicated key and keep a single occurrence.
  2. Generate connection strings from a single options object rather than string concatenation.

Example fix

// before
'mongodb://h/db?retryWrites=true&retryWrites=false'
// after
'mongodb://h/db?retryWrites=true'
Defensive patterns

Strategy: validation

Validate before calling

function assertNoDuplicateQueryKeys(uri: string) {
  const q = uri.split('?')[1];
  if (!q) return;
  const seen = new Set<string>();
  for (const pair of q.split('&')) {
    const key = pair.split('=')[0];
    if (!key) continue;
    if (key === 'readPreferenceTags') continue;
    if (seen.has(key)) throw new Error(`Duplicate URI option '${key}'`);
    seen.add(key);
  }
}

Prevention

When it happens

Trigger: A URI like 'mongodb://h/db?retryWrites=true&retryWrites=false' or 'mongodb://h/db?appname=a&appname=b'. Triggered while iterating url.searchParams.keys().

Common situations: Concatenating query strings, templating bugs that append the same param twice, or merging config fragments without deduping.

Related errors


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

Appendix: source

Thrown at src/connection_string.ts:292

  if (url.username !== '') {
    const auth: Document = {
      username: decodeURIComponent(url.username)
    };

    if (typeof url.password === 'string') {
      auth.password = decodeURIComponent(url.password);
    }

    urlOptions.set('auth', [auth]);
  }

  for (const key of url.searchParams.keys()) {
    const values = url.searchParams.getAll(key);

    const isReadPreferenceTags = /readPreferenceTags/i.test(key);

    if (!isReadPreferenceTags && values.length > 1) {
      throw new MongoInvalidArgumentError(
        `URI option "${key}" cannot appear more than once in the connection string`
      );
    }

    if (!isReadPreferenceTags && values.includes('')) {
      throw new MongoAPIError(`URI option "${key}" cannot be specified with no value`);
    }

    if (!urlOptions.has(key)) {
      urlOptions.set(key, values);
    }
  }

  const objectOptions = new CaseInsensitiveMap<unknown>(
    Object.entries(options).filter(([, v]) => v != null)
  );

  // Validate options that can only be provided by one of uri or object

View on GitHub (pinned to dce7939f86)