Automattic/mongoose · critical · MongooseError

The `uri` parameter to `openUri()` must be a string, got "${

Error message

The `uri` parameter to `openUri()` must be a string, got "${typeof uri}". Make sure the first parameter to `mongoose.connect()` or `mongoose.createConnection()` is a string.

What it means

NativeConnection.createClient() - the engine behind mongoose.connect() and mongoose.createConnection() - validates that the first parameter is a string URI before doing anything else. Passing undefined, an object, a MongoClient, or any other non-string throws this MongooseError reporting the actual typeof, because the connection string is the one required input for opening a connection.

Source

Thrown at lib/drivers/node-mongodb-native/connection.js:234

 * Implementation of `listDatabases()` for MongoDB driver
 *
 * @return {Promise}
 * @api public
 */

NativeConnection.prototype.listDatabases = async function listDatabases() {
  await this._waitForConnect();

  return await this.db.admin().listDatabases();
};

/*!
 * ignore
 */

NativeConnection.prototype.createClient = async function createClient(uri, options) {
  if (typeof uri !== 'string') {
    throw new MongooseError('The `uri` parameter to `openUri()` must be a ' +
      `string, got "${typeof uri}". Make sure the first parameter to ` +
      '`mongoose.connect()` or `mongoose.createConnection()` is a string.');
  }

  if (this._destroyCalled) {
    throw new MongooseError(
      'Connection has been closed and destroyed, and cannot be used for re-opening the connection. ' +
      'Please create a new connection with `mongoose.createConnection()` or `mongoose.connect()`.'
    );
  }

  if (this.readyState === STATES.connecting || this.readyState === STATES.connected) {
    if (this._connectionString !== uri) {
      throw new MongooseError('Can\'t call `openUri()` on an active connection with ' +
        'different connection strings. Make sure you aren\'t calling `mongoose.connect()` ' +
        'multiple times. See: https://mongoosejs.com/docs/connections.html#multiple_connections');
    }
  }

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Load environment config first (import 'dotenv/config' at the top) and fail fast if the URI is missing.
  2. Pass the string URI as the first argument: await mongoose.connect('mongodb://localhost:27017/test', options).
  3. If you already have a connected MongoClient, use conn.setClient(client) instead of passing the client to connect().
  4. Check for typos in the variable holding the URI.

Example fix

// before
import mongoose from 'mongoose';
await mongoose.connect(process.env.MONGO_URI); // undefined if .env not loaded

// after
import 'dotenv/config';
const uri = process.env.MONGO_URI;
if (typeof uri !== 'string' || uri.length === 0) {
  throw new Error('MONGO_URI is not set');
}
await mongoose.connect(uri);
Defensive patterns

Strategy: validation

Validate before calling

function assertMongoUri(uri) {
  if (typeof uri !== 'string' || uri.length === 0) {
    throw new Error(`Connection URI must be a non-empty string, got ${typeof uri}`);
  }
  return uri;
}
await mongoose.connect(assertMongoUri(process.env.MONGO_URI));

Type guard

function isMongoUri(v) {
  return typeof v === 'string' && v.startsWith('mongodb');
}

Prevention

When it happens

Trigger: mongoose.connect(process.env.MONGO_URI) when MONGO_URI is unset; passing an options object or a MongoClient as the first argument; mongoose.createConnection(dbConfigObject) instead of a URI string.

Common situations: Missing .env file or dotenv imported after the connect call; env var name typo (MONGO_URL vs MONGO_URI); code written for a client-first API (should use conn.setClient()); CI without configured secrets.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/4715a38e00a0bbf2. Report an issue: GitHub.