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;
};
/*!
* ignoreView on GitHub (pinned to 49cdab0136)
Solutions
- Close first: await mongoose.connection.close(); await mongoose.connection.setClient(client);.
- Pick one connection strategy at startup: URI-based connect() OR client-based setClient(), never both.
- 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
- Encapsulate 'connect by URI' vs 'adopt client' in one bootstrap function with mutually exclusive branches.
- Check connection.readyState before lifecycle-sensitive calls like setClient().
- Never call setClient on the shared default connection while requests are in flight; close() drains in-flight operations first.
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
- Connection has been closed and destroyed, and cannot be used
- Must call `setClient()` with an instance of MongoClient
- Cannot call `setClient()` with a MongoClient that you have n
- Arguments must be aggregate pipeline operators
- Invalid addFields() argument. Must be an object
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/54cb4b1c2430a2c6.
Report an issue: GitHub.