Automattic/mongoose · error · MongooseError

Cannot call `setClient()` on a connection that is already co

Error message

Cannot call `setClient()` on a connection that is already connected.

What it means

setClient() may only attach an external MongoClient while the connection is in the disconnected state. If the connection is currently connecting or connected (e.g. after mongoose.connect() or a prior openUri()), setClient throws this MongooseError because the connection is already bound to another client/topology.

Source

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

  const encryptedFieldsMap = Object.fromEntries(Object.entries(qeMappings).map(
    ([namespace, schema]) => ([namespace, schema._buildEncryptedFields()])
  ));

  return {
    schemaMap, encryptedFieldsMap
  };
};

/*!
 * ignore
 */

NativeConnection.prototype.setClient = function setClient(client) {
  if (!(client instanceof mongodb.MongoClient)) {
    throw new MongooseError('Must call `setClient()` with an instance of MongoClient');
  }
  if (this.readyState !== STATES.disconnected) {
    throw new MongooseError('Cannot call `setClient()` on a connection that is already connected.');
  }
  if (client.topology == null) {
    throw new MongooseError('Cannot call `setClient()` with a MongoClient that you have not called `connect()` on yet.');
  }

  this._connectionString = client.s.url;
  _setClient(this, client, {}, client.s.options.dbName);

  for (const model of Object.values(this.models)) {
    // Errors handled internally, so safe to ignore error
    model.init().catch(function $modelInitNoop() {});
  }

  return this;
};

/*!
 * ignore

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Close first: await mongoose.connection.close(); await mongoose.connection.setClient(client);.
  2. Pick one connection strategy at startup: URI-based connect() OR client-based setClient(), never both.
  3. For multiple clients, use separate connections: const c2 = mongoose.createConnection(); await c2.setClient(client2);.

Example fix

// before
await mongoose.connect(uri);
await mongoose.connection.setClient(client); // throws: already connected

// after
await mongoose.connection.close();
await mongoose.connection.setClient(client);
Defensive patterns

Strategy: validation

Validate before calling

async function attachClient(conn, client) {
  if (conn.readyState !== 0) { // 0 === STATES.disconnected
    await conn.close();
  }
  return conn.setClient(client);
}

Type guard

function isDisconnected(conn) {
  return conn.readyState === 0; // STATES.disconnected
}

Prevention

When it happens

Trigger: await mongoose.connect(uri); await mongoose.connection.setClient(client); - also calling setClient after openUri(), or calling setClient twice without closing in between.

Common situations: Bootstrap code that both connects by URI and then tries to hand over a pre-built client; runtime switch-database features implemented via setClient on the live default connection.

Related errors


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