Automattic/mongoose · error · MongooseError
Query.prototype.estimatedDocumentCount() no longer accepts a
Error message
Query.prototype.estimatedDocumentCount() no longer accepts a callback
What it means
Query.prototype.estimatedDocumentCount(options) throws when its options parameter or the second positional argument is a function. The method takes no other parameters (it counts via collection metadata, no filter), so a function argument is almost always a leftover callback from the Mongoose 6-and-earlier era.
Source
Thrown at lib/query.js:2958
*
* This function triggers the following middleware.
*
* - `estimatedDocumentCount()`
*
* #### Example:
*
* await Model.find().estimatedDocumentCount();
*
* @param {object} [options] passed transparently to the [MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/EstimatedDocumentCountOptions.html)
* @return {Query} this
* @see estimatedDocumentCount https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#estimatedDocumentCount
* @api public
*/
Query.prototype.estimatedDocumentCount = function(options) {
if (typeof options === 'function' ||
typeof arguments[1] === 'function') {
throw new MongooseError('Query.prototype.estimatedDocumentCount() no longer accepts a callback');
}
this.op = 'estimatedDocumentCount';
if (options != null) {
this.setOptions(options);
}
return this;
};
/**
* Specifies this query as a `countDocuments()` query. Behaves like `count()`,
* except it always does a full collection scan when passed an empty filter `{}`.
*
* There are also minor differences in how `countDocuments()` handles
* [`$where` and a couple geospatial operators](https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#countDocuments).
* versus `count()`.View on GitHub (pinned to 49cdab0136)
Solutions
- Use await: const n = await Model.estimatedDocumentCount()
- Pass a driver options object or nothing — never a function
- Use .countDocuments(filter) instead when you need a filtered count
Example fix
// before
Model.estimatedDocumentCount((err, count) => {
res.json({ total: count });
});
// after
const count = await Model.estimatedDocumentCount();
res.json({ total: count }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof options === 'function') {
throw new TypeError('estimatedDocumentCount takes an options object, not a callback');
}
const count = await Model.estimatedDocumentCount(options); Type guard
const isLegacyCallback = (v) => typeof v === 'function';
Try / catch
try {
const n = await Model.estimatedDocumentCount();
} catch (err) {
if (err?.message?.includes('no longer accepts a callback')) {
// remove the callback from the estimatedDocumentCount call site
}
throw err;
} Prevention
- estimatedDocumentCount takes only a driver options object — never a filter or callback
- Use countDocuments(filter, options) when you need to count a subset
- Migrate all count-style helpers to async/await before upgrading to Mongoose 7
When it happens
Trigger: Model.estimatedDocumentCount(cb); query.estimatedDocumentCount({}, cb); a promise-returning helper or mapper passed in the options slot.
Common situations: Pre-Mongoose-7 stats/dashboard code using callbacks; converting removed Model.count(cb) calls to estimatedDocumentCount while keeping the callback signature.
Related errors
- Query.prototype.countDocuments() no longer accepts a callbac
- Query.prototype.find() no longer accepts a callback
- Query.prototype.findOne() no longer accepts a callback
- Query.prototype.distinct() no longer accepts a callback
- Query.prototype.deleteOne() no longer accepts a callback
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/bcd9a4f35d2b5c96.
Report an issue: GitHub.