Automattic/mongoose · error · MongooseError
Model.findByIdAndDelete() no longer accepts a callback
Error message
Model.findByIdAndDelete() no longer accepts a callback
What it means
Mongoose 7 removed callback support from all Model and Query APIs; findByIdAndDelete() delegates to findOneAndDelete({ _id: id }) and is promise-only. The guard throws this MongooseError synchronously if any of arguments[0] through arguments[2] is a function (id, options, or trailing callback).
Source
Thrown at lib/model.js:2601
*
* This function triggers the following middleware.
*
* - `findOneAndDelete()`
*
* @param {object|number|string} id value of `_id` to query by
* @param {object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
* @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
* @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.
* @return {Query}
* @see Model.findOneAndDelete https://mongoosejs.com/docs/api/model.html#Model.findOneAndDelete()
* @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
*/
Model.findByIdAndDelete = function(id, options) {
_checkContext(this, 'findByIdAndDelete');
if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function' || typeof arguments[2] === 'function') {
throw new MongooseError('Model.findByIdAndDelete() no longer accepts a callback');
}
return this.findOneAndDelete({ _id: id }, options);
};
/**
* Issue a MongoDB `findOneAndReplace()` command.
*
* Finds a matching document, replaces it with the provided doc, and returns the document.
*
* This function triggers the following query middleware.
*
* - `findOneAndReplace()`
*
* #### Example:
*
* A.findOneAndReplace(filter, replacement, options) // return Query
* A.findOneAndReplace(filter, replacement) // returns QueryView on GitHub (pinned to 49cdab0136)
Solutions
- Use await: await Model.findByIdAndDelete(id); wrapped in try/catch
- Or chain .then()/.catch() on the returned Query
- Sweep the codebase for callback-style Model method calls as part of the Mongoose 7 migration checklist
- Pin mongoose@6 as a stopgap only, with a migration plan
- Enable TypeScript type-checking so callback overloads fail to compile
Example fix
// before
User.findByIdAndDelete(id, (err) => { ... });
// after
await User.findByIdAndDelete(id); Defensive patterns
Strategy: validation
Validate before calling
function assertNoCallbacks(fnName, args) {
const i = args.findIndex(a => typeof a === 'function');
if (i !== -1) throw new TypeError(`${fnName}: callbacks removed in Mongoose 7; use await`);
}
// assertNoCallbacks('findByIdAndDelete', [id, options]); Try / catch
try {
await Model.findByIdAndDelete(id);
} catch (err) {
if (/no longer accepts a callback/.test(err.message)) { /* migrate call site */ }
else throw err;
} Prevention
- Grep for findByIdAndDelete(..., function / => patterns during upgrades
- Keep delete helpers promise-based and centralize them so all call sites follow one style
- TypeScript catches removed overloads at compile time
When it happens
Trigger: Calling Model.findByIdAndDelete(id, options, callback) or Model.findByIdAndDelete(id, callback) in Mongoose 7/8. Also fires when a function is mistakenly passed as the id.
Common situations: Mongoose 6 to 7/8 upgrades where delete-by-id call sites were not migrated; older codebases following pre-2022 tutorials that use callbacks for deletions.
Related errors
- Model.findOneAndDelete() no longer accepts a callback
- Model.findByIdAndUpdate() no longer accepts a callback
- Model.findOneAndReplace() no longer accepts a callback
- Model.create() 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/53b7956775dedaec.
Report an issue: GitHub.