{"record":{"id":"d65b556518f97639","repo":"Automattic/mongoose","slug":"model-findone-no-longer-accepts-a-callback","errorCode":null,"errorMessage":"Model.findOne() no longer accepts a callback","messagePattern":"Model\\.findOne\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":2204,"sourceCode":" *     // Model.findOne() no longer accepts a callback\n *\n *     // Select only the adventures name and length\n *     await Adventure.findOne({ country: 'Croatia' }, 'name length').exec();\n *\n * @param {object} [conditions]\n * @param {object|string|string[]} [projection] optional fields to return, see [`Query.prototype.select()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.select())\n * @param {object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())\n * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.\n * @return {Query}\n * @see field selection https://mongoosejs.com/docs/api/query.html#Query.prototype.select()\n * @see lean queries https://mongoosejs.com/docs/tutorials/lean.html\n * @api public\n */\n\nModel.findOne = function findOne(conditions, projection, options) {\n  _checkContext(this, 'findOne');\n  if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function' || typeof arguments[2] === 'function') {\n    throw new MongooseError('Model.findOne() no longer accepts a callback');\n  }\n\n  const mq = new this.Query({}, {}, this, this.$__collection);\n  mq.select(projection);\n  mq.setOptions(options);\n\n  return mq.findOne(conditions);\n};\n\n/**\n * Estimates the number of documents in the MongoDB collection. Faster than\n * using `countDocuments()` for large collections because\n * `estimatedDocumentCount()` uses collection metadata rather than scanning\n * the entire collection.\n *\n * #### Example:\n *\n *     const numAdventures = await Adventure.estimatedDocumentCount();","sourceCodeStart":2186,"sourceCodeEnd":2222,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L2186-L2222","documentation":"Model.findOne(conditions, projection, options) returns a Query resolving to the first match or null. Callbacks were removed in Mongoose 7; a function in any of the first three positional slots throws immediately inside findOne itself.","triggerScenarios":"`User.findOne({ email }, (err, user) => ...)`; login/lookup handlers written callback-style; passing a callback in place of `options`.","commonSituations":"Authentication flows (`findOne({ email })`) ported from old tutorials; the upgrade from mongoose 6 to 7+.","solutions":["Await it: `const user = await User.findOne({ email });`","Use `.orFail()` when a missing document should reject instead of resolving null","Sweep `findOne\\(` call sites for function arguments during migration"],"exampleFix":"// before\nUser.findOne({ email }, (err, user) => { if (err) throw err; ... });\n\n// after\nconst user = await User.findOne({ email });","handlingStrategy":"validation","validationCode":"const isFn = (a) => typeof a === 'function';\nif ([conditions, projection, options].some(isFn)) {\n  throw new TypeError('findOne() is promise-only');\n}\nconst user = await User.findOne(conditions, projection, options);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Auth-style lookups should use .orFail() or explicit null checks after migration","Cover findOne call sites in the same mechanical migration commit as find()"],"tags":["mongoose","callback-removed","promise","query","migration"],"backgroundTag":"mongoose-callback-removed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}