Automattic/mongoose · error · MongooseError

Connection.prototype.startSession() no longer accepts a call

Error message

Connection.prototype.startSession() no longer accepts a callback

What it means

Mongoose 7 removed all callback-style APIs; startSession() is async and returns a Promise<ClientSession>. An explicit guard throws when a function is detected in the second argument position so legacy callback code fails loudly at the call site instead of the callback being silently ignored (arguments[1] would otherwise never run).

Source

Thrown at lib/connection.js:689

 *     let doc = await Person.findOne({ name: 'Ned Stark' }, null, { session });
 *     await doc.deleteOne();
 *     // `doc` will always be null, even if reading from a replica set
 *     // secondary. Without causal consistency, it is possible to
 *     // get a doc back from the below query if the query reads from a
 *     // secondary that is experiencing replication lag.
 *     doc = await Person.findOne({ name: 'Ned Stark' }, null, { session, readPreference: 'secondary' });
 *
 *
 * @method startSession
 * @param {object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/7.0/classes/MongoClient.html#startSession)
 * @param {boolean} [options.causalConsistency=true] set to false to disable causal consistency
 * @return {Promise<ClientSession>} promise that resolves to a MongoDB driver `ClientSession`
 * @api public
 */

Connection.prototype.startSession = async function startSession(options) {
  if (arguments.length >= 2 && typeof arguments[1] === 'function') {
    throw new MongooseError('Connection.prototype.startSession() no longer accepts a callback');
  }

  await this._waitForConnect();

  const session = this.client.startSession(options);
  return session;
};

/**
 * _Requires MongoDB >= 3.6.0._ Executes the wrapped async function
 * in a transaction. Mongoose will commit the transaction if the
 * async function executes successfully and attempt to retry if
 * there was a retriable error.
 *
 * Calls the MongoDB driver's [`session.withTransaction()`](https://mongodb.github.io/node-mongodb-native/7.0/classes/ClientSession.html#withTransaction),
 * but also handles resetting Mongoose document state as shown below.
 *
 * #### Example:

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Remove the callback and await: const session = await conn.startSession()
  2. Move the old callback body into try/catch around awaited calls
  3. When upgrading, grep the repo for startSession( calls taking two arguments

Example fix

// before
conn.startSession({ causalConsistency: true }, (err, session) => { /* ... */ });

// after
const session = await conn.startSession({ causalConsistency: true });
Defensive patterns

Strategy: validation

Validate before calling

function startSessionSafe(options) {
  if (typeof options === 'function') {
    throw new TypeError('callback passed to promise-only startSession');
  }
  return conn.startSession(options);
}

Prevention

When it happens

Trigger: conn.startSession({ causalConsistency: false }, (err, session) => { ... }) — an options object followed by a callback function (arguments.length >= 2 with arguments[1] a function).

Common situations: Upgrading a codebase from mongoose 6.x or earlier to 7/8/9; copying pre-promise-era tutorials or Stack Overflow answers; old transaction helpers written callback-style.

Related errors


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