{"record":{"id":"e8c56b4dbd000f76","repo":"Automattic/mongoose","slug":"document-prototype-validate-no-longer-accepts-a","errorCode":null,"errorMessage":"Document.prototype.validate() no longer accepts a callback","messagePattern":"Document\\.prototype\\.validate\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/document.js","lineNumber":2741,"sourceCode":" *\n * #### Example:\n *\n *     await doc.validate({ validateModifiedOnly: false, pathsToSkip: ['name', 'email']});\n *\n * @param {Array|string} [pathsToValidate] list of paths to validate. If set, Mongoose will validate only the modified paths that are in the given list.\n * @param {object} [options] internal options\n * @param {boolean} [options.validateModifiedOnly=false] if `true` mongoose validates only modified paths.\n * @param {Array|string} [options.pathsToSkip] list of paths to skip. If set, Mongoose will validate every modified path that is not in this list.\n * @param {boolean|object} [options.middleware=true] set to `false` to skip all user-defined middleware\n * @param {boolean} [options.middleware.pre=true] set to `false` to skip only pre hooks\n * @param {boolean} [options.middleware.post=true] set to `false` to skip only post hooks\n * @return {Promise} Returns a Promise.\n * @api public\n */\n\nDocument.prototype.validate = async function validate(pathsToValidate, options) {\n  if (typeof pathsToValidate === 'function' || typeof options === 'function' || typeof arguments[2] === 'function') {\n    throw new MongooseError('Document.prototype.validate() no longer accepts a callback');\n  }\n  this.$op = 'validate';\n\n  if (arguments.length === 1) {\n    if (typeof arguments[0] === 'object' && !Array.isArray(arguments[0])) {\n      options = arguments[0];\n      pathsToValidate = null;\n    }\n  }\n  if (options && typeof options.pathsToSkip === 'string') {\n    const isOnePathOnly = options.pathsToSkip.indexOf(' ') === -1;\n    options.pathsToSkip = isOnePathOnly ? [options.pathsToSkip] : options.pathsToSkip.split(' ');\n  }\n  const _skipParallelValidateCheck = options?._skipParallelValidateCheck;\n\n  if (this.$isSubdocument != null) {\n    // Skip parallel validate check for subdocuments\n  } else if (this.$__.validating && !_skipParallelValidateCheck) {","sourceCodeStart":2723,"sourceCodeEnd":2759,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/document.js#L2723-L2759","documentation":"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.","triggerScenarios":"Legacy Mongoose <= 6 code: `doc.validate(function(err) {...})`, `doc.validate(['name'], cb)`, or `doc.validate({ validateModifiedOnly: true }, cb)`.","commonSituations":"Upgrading a Mongoose 6 codebase to 7/8; copied tutorial snippets using node-style callbacks; wrapper libraries that accept callbacks and forward them verbatim.","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"],"exampleFix":"// before\ndoc.validate(function(err) { if (err) return next(err); next(); });\n\n// after\ntry {\n  await doc.validate();\n  next();\n} catch (err) {\n  next(err);\n}","handlingStrategy":"validation","validationCode":"// Wrapper that refuses callback-style usage before it reaches mongoose\nfunction validateDoc(doc, ...args) {\n  if (args.some(a => typeof a === 'function')) {\n    throw new TypeError('Callbacks are not supported; await the returned promise instead');\n  }\n  return doc.validate(...args);\n}","typeGuard":"const isNotCallback = (...args) => args.every(a => typeof a !== 'function');","tryCatchPattern":null,"preventionTips":["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"],"tags":["mongoose","callbacks","promises","migration","validate"],"backgroundTag":"mongoose-callbacks-removed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}