Automattic/mongoose · error · MongooseError
Document.prototype.validate() no longer accepts a callback
Error message
Document.prototype.validate() no longer accepts a callback
What it means
Mongoose 7 removed callback support from every API, including Document#validate(). If any of the validate() arguments is a function (as pathsToValidate, as options, or a third argument), validate() throws immediately instead of starting validation.
Source
Thrown at lib/document.js:2741
*
* #### Example:
*
* await doc.validate({ validateModifiedOnly: false, pathsToSkip: ['name', 'email']});
*
* @param {Array|string} [pathsToValidate] list of paths to validate. If set, Mongoose will validate only the modified paths that are in the given list.
* @param {object} [options] internal options
* @param {boolean} [options.validateModifiedOnly=false] if `true` mongoose validates only modified paths.
* @param {Array|string} [options.pathsToSkip] list of paths to skip. If set, Mongoose will validate every modified path that is not in this list.
* @param {boolean|object} [options.middleware=true] set to `false` to skip all user-defined middleware
* @param {boolean} [options.middleware.pre=true] set to `false` to skip only pre hooks
* @param {boolean} [options.middleware.post=true] set to `false` to skip only post hooks
* @return {Promise} Returns a Promise.
* @api public
*/
Document.prototype.validate = async function validate(pathsToValidate, options) {
if (typeof pathsToValidate === 'function' || typeof options === 'function' || typeof arguments[2] === 'function') {
throw new MongooseError('Document.prototype.validate() no longer accepts a callback');
}
this.$op = 'validate';
if (arguments.length === 1) {
if (typeof arguments[0] === 'object' && !Array.isArray(arguments[0])) {
options = arguments[0];
pathsToValidate = null;
}
}
if (options && typeof options.pathsToSkip === 'string') {
const isOnePathOnly = options.pathsToSkip.indexOf(' ') === -1;
options.pathsToSkip = isOnePathOnly ? [options.pathsToSkip] : options.pathsToSkip.split(' ');
}
const _skipParallelValidateCheck = options?._skipParallelValidateCheck;
if (this.$isSubdocument != null) {
// Skip parallel validate check for subdocuments
} else if (this.$__.validating && !_skipParallelValidateCheck) {View on GitHub (pinned to 49cdab0136)
Solutions
- Await the promise: `try { await doc.validate(); } catch (err) { ... }`
- Or chain: `doc.validate().then(next).catch(errHandler)`
- For synchronous checks use `doc.validateSync()` (returns a ValidationError)
- Grep the codebase for `validate(function` and `validate(cb` patterns and migrate them all
Example fix
// before
doc.validate(function(err) { if (err) return next(err); next(); });
// after
try {
await doc.validate();
next();
} catch (err) {
next(err);
} Defensive patterns
Strategy: validation
Validate before calling
// Wrapper that refuses callback-style usage before it reaches mongoose
function validateDoc(doc, ...args) {
if (args.some(a => typeof a === 'function')) {
throw new TypeError('Callbacks are not supported; await the returned promise instead');
}
return doc.validate(...args);
} Type guard
const isNotCallback = (...args) => args.every(a => typeof a !== 'function');
Prevention
- During Mongoose 6 -> 7/8 migrations, grep for validate(function, findOne(function, save(function
- Replace node-style callbacks with await or .then()/.catch()
- Use validateSync() when synchronous validation semantics are wanted
When it happens
Trigger: Legacy Mongoose <= 6 code: `doc.validate(function(err) {...})`, `doc.validate(['name'], cb)`, or `doc.validate({ validateModifiedOnly: true }, cb)`.
Common situations: Upgrading a Mongoose 6 codebase to 7/8; copied tutorial snippets using node-style callbacks; wrapper libraries that accept callbacks and forward them verbatim.
Related errors
- Model.prototype.save() no longer accepts a callback
- Model.prototype.deleteOne() no longer accepts a callback
- Model.exists() no longer accepts a callback
- Connection.prototype.startSession() no longer accepts a call
- Connection.prototype.dropCollection() no longer accepts a ca
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/e8c56b4dbd000f76.
Report an issue: GitHub.