mongodb/node-mongodb-native · error · MongoAPIError

URI option "${key}" cannot be specified with no value

Error message

URI option "${key}" cannot be specified with no value

What it means

Thrown during option parsing when a URI query parameter is present with an empty value (e.g. ?retryWrites=), except for readPreferenceTags. The driver collects values via getAll(key) and rejects any key whose value list contains the empty string. It is a MongoAPIError raised while scanning url.searchParams.

Source

Thrown at src/connection_string.ts:298

      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

  if (urlOptions.has('serverApi')) {
    throw new MongoParseError(
      'URI cannot contain `serverApi`, it can only be passed to the client'
    );
  }

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Omit the key entirely when the value is empty rather than emitting 'key='.
  2. Filter out empty-value params before assembling the URI.
  3. Prefer the options object for optional settings so absent = unset.
  4. Validate the final URI with new URL(uri) and assert no searchParam value is ''.

Example fix

// before
const uri = `mongodb://h/db?appname=${process.env.APP_NAME}`; // empty -> 'appname='
// after
const params = new URLSearchParams();
if (process.env.APP_NAME) params.set('appname', process.env.APP_NAME);
const uri = `mongodb://h/db${params.toString() ? '?' + params : ''}`;
Defensive patterns

Strategy: validation

Validate before calling

function dropEmptyParams(uri: string): string {
  const [base, query] = uri.split('?');
  if (!query) return uri;
  const params = new URLSearchParams();
  for (const [k, v] of new URLSearchParams(query).entries()) {
    if (v !== '') params.append(k, v);
  }
  const qs = params.toString();
  return qs ? `${base}?${qs}` : base;
}

Type guard

const hasNoEmptyParams = (uri: string): boolean => {
  const q = uri.split('?')[1];
  if (!q) return true;
  for (const [, v] of new URLSearchParams(q).entries()) {
    if (v === '') return false;
  }
  return true;
};

Try / catch

try {
  await client.connect();
} catch (e) {
  if (e instanceof MongoAPIError && /cannot be specified with no value/.test(e.message)) {
    return new MongoClient(dropEmptyParams(uri)).connect();
  }
  throw e;
}

Prevention

When it happens

Trigger: URI like mongodb://h/db?appname= or ?retryWrites=&tls=true; templating an option from an unset env var producing 'key='; URL builders that append 'key=' when the value is empty; trailing '&' creating an empty segment.

Common situations: Interpolating optional env vars into the URI without omitting the key when unset; copy-paste leaving a placeholder value blank; URI builders that always append a key even when the value is missing.

Related errors


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