Automattic/mongoose · error · MongooseError

Model.listIndexes() no longer accepts a callback

Error message

Model.listIndexes() no longer accepts a callback

What it means

Model.listIndexes() returns the indexes currently defined in MongoDB (which can differ from schema indexes depending on autoIndex usage). It takes no arguments in Mongoose 7+; passing a callback function throws immediately — it never reaches the driver.

Source

Thrown at lib/model.js:1619

  }

  return toDrop;
}

/**
 * Lists the indexes currently defined in MongoDB. This may or may not be
 * the same as the indexes defined in your schema depending on whether you
 * use the [`autoIndex` option](https://mongoosejs.com/docs/guide.html#autoIndex) and if you
 * build indexes manually.
 *
 * @return {Promise}
 * @api public
 */

Model.listIndexes = async function listIndexes() {
  _checkContext(this, 'listIndexes');
  if (typeof arguments[0] === 'function') {
    throw new MongooseError('Model.listIndexes() no longer accepts a callback');
  }

  if (this.$__collection.buffer) {
    await new Promise(resolve => {
      this.$__collection.addQueue(resolve);
    });
  }

  return this.$__collection.listIndexes().toArray();
};

/**
 * Sends `createIndex` commands to mongo for each index declared in the schema.
 * The `createIndex` commands are sent in series.
 *
 * #### Example:
 *
 *     await Event.ensureIndexes();

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Await it: `const indexes = await User.listIndexes();`
  2. The result is an array-like from the driver cursor; iterate with `for...of` or spread `[...]`
  3. Compare against `User.schema.indexes()` for drift detection instead of hand-rolled callback diffing

Example fix

// before
User.listIndexes((err, indexes) => { ... });

// after
const indexes = await User.listIndexes();
Defensive patterns

Strategy: validation

Validate before calling

if (typeof arguments[0] === 'function') throw new TypeError('listIndexes() takes no arguments');
const indexes = await User.listIndexes();

Try / catch

try {
  const indexes = await User.listIndexes();
} catch (err) {
  if (err?.codeName === 'NamespaceNotFound') return []; // collection not created yet
  throw err;
}

Prevention

When it happens

Trigger: `User.listIndexes(cb)`; `User.listIndexes().toArray(cb)` confusion (the promise already resolves to an array-like); diagnostic scripts from the callback era.

Common situations: Post-migration leftovers; monitoring/diagnostic endpoints written for Mongoose 6.

Related errors


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