{"record":{"id":"e9910197116bb225","repo":"Automattic/mongoose","slug":"query-prototype-find-no-longer-accepts-a-callbac","errorCode":null,"errorMessage":"Query.prototype.find() no longer accepts a callback","messagePattern":"Query\\.prototype\\.find\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/query.js","lineNumber":2550,"sourceCode":"/**\n * Find all documents that match `selector`. The result will be an array of documents.\n *\n * If there are too many documents in the result to fit in memory, use\n * [`Query.prototype.cursor()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.cursor())\n *\n * #### Example:\n *\n *     const arr = await Movie.find({ year: { $gte: 1980, $lte: 1989 } });\n *\n * @param {object|ObjectId} [filter] mongodb filter. If not specified, returns all documents.\n * @return {Query} this\n * @api public\n */\n\nQuery.prototype.find = function(conditions) {\n  if (typeof conditions === 'function' ||\n      typeof arguments[1] === 'function') {\n    throw new MongooseError('Query.prototype.find() no longer accepts a callback');\n  }\n\n  this.op = 'find';\n\n  if (canMerge(conditions)) {\n    this.merge(conditions);\n\n    prepareDiscriminatorCriteria(this);\n  } else if (conditions != null) {\n    this.error(new ObjectParameterError(conditions, 'filter', 'find'));\n  }\n\n  return this;\n};\n\n/**\n * Merges another Query or conditions object into this one.\n *","sourceCodeStart":2532,"sourceCodeEnd":2568,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/query.js#L2532-L2568","documentation":"Mongoose 7.0 removed callback-style execution from all query methods; Query.prototype.find() throws immediately if its first argument or the second positional argument (arguments[1]) is a function. The throw happens at query-construction time, before any database call, so legacy code like Model.find({}, cb) fails fast instead of silently never invoking the callback.","triggerScenarios":"Model.find({}, (err, docs) => {...}); Model.find(cb); passing a function in the filter slot (.find(someMapper)); wrappers built on the `async` library (async.waterfall) that forward nodeback callbacks positionally.","commonSituations":"Upgrading mongoose 6 to 7/8 without migrating callbacks (deprecated in 6, removed in 7); old tutorials and Stack Overflow snippets; large legacy codebases where a single un-migrated call throws on the first request after deploy.","solutions":["Use async/await: const docs = await Model.find({})","Or promise chaining: Model.find({}).then(docs => ...).catch(err => ...)","Grep the codebase for .find( calls with a trailing function argument and remove the callbacks; follow the Mongoose 6 to 7 migration guide"],"exampleFix":"// before (mongoose 6 and earlier)\nModel.find({ active: true }, (err, docs) => {\n  if (err) return next(err);\n  res.json(docs);\n});\n\n// after (mongoose 7/8)\ntry {\n  const docs = await Model.find({ active: true });\n  res.json(docs);\n} catch (err) {\n  next(err);\n}","handlingStrategy":"validation","validationCode":"// Optional dev-time wrapper that fails fast with a clearer message\nfunction findSafe(model, filter, options) {\n  if ([filter, options].some(v => typeof v === 'function')) {\n    throw new Error('find() is promise-only in Mongoose 7+; remove the callback');\n  }\n  return model.find(filter, options);\n}","typeGuard":"const isLegacyCallback = (v) => typeof v === 'function';","tryCatchPattern":"try {\n  const docs = await Model.find(filter);\n} catch (err) {\n  if (err?.message?.includes('no longer accepts a callback')) {\n    // a call site still uses the removed callback signature: fix it there\n  }\n  throw err;\n}","preventionTips":["Search for 'err =>' near Mongoose calls when upgrading versions","Adopt async/await uniformly; Mongoose 7+ has no callback path","Keep model access in typed wrappers so stray callbacks are caught in code review"],"tags":["mongoose","callback","promise","migration","breaking-change","find"],"backgroundTag":"legacy-callback-removed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}