{"record":{"id":"bcd9a4f35d2b5c96","repo":"Automattic/mongoose","slug":"query-prototype-estimateddocumentcount-no-longer","errorCode":null,"errorMessage":"Query.prototype.estimatedDocumentCount() no longer accepts a callback","messagePattern":"Query\\.prototype\\.estimatedDocumentCount\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/query.js","lineNumber":2958,"sourceCode":" *\n * This function triggers the following middleware.\n *\n * - `estimatedDocumentCount()`\n *\n * #### Example:\n *\n *     await Model.find().estimatedDocumentCount();\n *\n * @param {object} [options] passed transparently to the [MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/EstimatedDocumentCountOptions.html)\n * @return {Query} this\n * @see estimatedDocumentCount https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#estimatedDocumentCount\n * @api public\n */\n\nQuery.prototype.estimatedDocumentCount = function(options) {\n  if (typeof options === 'function' ||\n      typeof arguments[1] === 'function') {\n    throw new MongooseError('Query.prototype.estimatedDocumentCount() no longer accepts a callback');\n  }\n\n  this.op = 'estimatedDocumentCount';\n\n  if (options != null) {\n    this.setOptions(options);\n  }\n\n  return this;\n};\n\n/**\n * Specifies this query as a `countDocuments()` query. Behaves like `count()`,\n * except it always does a full collection scan when passed an empty filter `{}`.\n *\n * There are also minor differences in how `countDocuments()` handles\n * [`$where` and a couple geospatial operators](https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#countDocuments).\n * versus `count()`.","sourceCodeStart":2940,"sourceCodeEnd":2976,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/query.js#L2940-L2976","documentation":"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.","triggerScenarios":"Model.estimatedDocumentCount(cb); query.estimatedDocumentCount({}, cb); a promise-returning helper or mapper passed in the options slot.","commonSituations":"Pre-Mongoose-7 stats/dashboard code using callbacks; converting removed Model.count(cb) calls to estimatedDocumentCount while keeping the callback signature.","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"],"exampleFix":"// before\nModel.estimatedDocumentCount((err, count) => {\n  res.json({ total: count });\n});\n\n// after\nconst count = await Model.estimatedDocumentCount();\nres.json({ total: count });","handlingStrategy":"validation","validationCode":"if (typeof options === 'function') {\n  throw new TypeError('estimatedDocumentCount takes an options object, not a callback');\n}\nconst count = await Model.estimatedDocumentCount(options);","typeGuard":"const isLegacyCallback = (v) => typeof v === 'function';","tryCatchPattern":"try {\n  const n = await Model.estimatedDocumentCount();\n} catch (err) {\n  if (err?.message?.includes('no longer accepts a callback')) {\n    // remove the callback from the estimatedDocumentCount call site\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["mongoose","callback","promise","migration","breaking-change","count"],"backgroundTag":"legacy-callback-removed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}