Automattic/mongoose · error · MongooseError
Model.distinct() no longer accepts a callback
Error message
Model.distinct() no longer accepts a callback
What it means
Model.distinct(field, conditions, options) runs a distinct command on one field with casting and returns a Query resolving to the array of distinct values. Callbacks were removed in Mongoose 7; a function in any of the first three slots throws before the Query is created.
Source
Thrown at lib/model.js:2297
/**
* Creates a Query for a `distinct` operation.
*
* #### Example:
*
* const query = Link.distinct('url');
* query.exec();
*
* @param {string} field
* @param {object} [conditions] optional
* @param {object} [options] optional
* @return {Query}
* @api public
*/
Model.distinct = function distinct(field, conditions, options) {
_checkContext(this, 'distinct');
if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function' || typeof arguments[2] === 'function') {
throw new MongooseError('Model.distinct() no longer accepts a callback');
}
const mq = new this.Query({}, {}, this, this.$__collection);
if (options != null) {
mq.setOptions(options);
}
return mq.distinct(field, conditions);
};
/**
* Creates a Query, applies the passed conditions, and returns the Query.
*
* For example, instead of writing:
*
* User.find({ age: { $gte: 21, $lte: 65 } });
*
* we can instead write:View on GitHub (pinned to 49cdab0136)
Solutions
- Await it: `const roles = await User.distinct('role');`
- Migrate the surrounding callback flow to async/await at the same time to avoid partial rewrites
- Add `distinct\(` to the migration grep list alongside find/findOne/count
Example fix
// before
User.distinct('role', (err, roles) => { ... });
// after
const roles = await User.distinct('role'); Defensive patterns
Strategy: validation
Validate before calling
const isFn = (a) => typeof a === 'function';
if ([field, conditions, options].some(isFn)) {
throw new TypeError('distinct() is promise-only');
}
const values = await User.distinct(field, conditions); Prevention
- Include less-common statics (distinct, countDocuments) in the migration checklist — they are the ones that slip through
- Prefer promise-based reporting utilities so callback helpers from legacy libs are not reused
When it happens
Trigger: `User.distinct('role', {}, cb)`; `User.distinct('email', cb)`; report/export builders written callback-style.
Common situations: Aggregation-lite helpers (distinct roles, tags) from older codebases; migration sweep gaps for less-common statics.
Related errors
- Model.init() no longer accepts a callback
- Model.createCollection() no longer accepts a callback
- Model.syncIndexes() no longer accepts a callback
- Model.cleanIndexes() no longer accepts a callback
- Model.listIndexes() no longer accepts a callback
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/2cb14e44901f39b0.
Report an issue: GitHub.