Built-in & Custom Schema Validations with Custom Error Messages0%

Built-in & Custom Schema Validations with Custom Error Messages

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Built-in & Custom Schema Validations with Custom Error Messages

Data integrity starts at the model layer. Mongoose provides built-in validators for numbers, strings, dates, and arrays, as well as the ability to define asynchronous Custom Validators that enforce complex business rules before data reaches the database.


1. Built-in Mongoose Validators

ValidatorTarget TypesDescriptionExample
requiredAll typesEnsures field exists and is not nullrequired: [true, 'Email is mandatory']
min / maxNumber, DateEnforces minimum and maximum boundsmin: [0, 'Price must be positive']
minlength / maxlengthStringRestricts string character countminlength: [8, 'Password too short']
enumStringRestricts string to allowed array of valuesenum: ['draft', 'published', 'archived']
matchStringValidates string against a Regular Expressionmatch: [/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/, 'Invalid email']

2. Writing Custom Asynchronous Validators

Custom validators use the validate property. You can supply a synchronous function, an asynchronous function returning a Promise/Boolean, or an async validator with custom error messages:

JavaScript
import { Schema, model } from 'mongoose';
 
const userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true, // Note: unique creates a database index, not a validator!
validate: {
validator: function(v) {
return /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(v);
},
message: props => `${props.value} is not a valid email address!`
}
},
discountPrice: {
type: Number,
validate: {
validator: function(val) {
// 'this' points to the current document being created
return val < this.price;
},
message: 'Discount price ({VALUE}) must be less than the regular price'
}
},
price: {
type: Number,
required: true
}
});

Note: In custom validators, this only points to the document on new document creation (.save()). For updates via findOneAndUpdate(), use { runValidators: true, context: 'query' }.


3. Triggering Validation on Updates

By default, Mongoose executes schema validators when creating documents via .save() or .create(). When running update queries like findByIdAndUpdate() or updateOne(), Mongoose skips validators by default for performance!

To force validation on updates, you must pass { runValidators: true }:

JavaScript
const updatedCourse = await Course.findByIdAndUpdate(
courseId,
{ price: -50 }, // Invalid!
{
new: true, // Return updated document
runValidators: true // Enforces schema validation rules!
}
);

Interactive Quiz

Multiple Choice Questions

Question 1
Why must { runValidators: true } be explicitly specified when calling findByIdAndUpdate() in Mongoose?
Question 2
Is unique: true in a Mongoose schema a validator?
Question 3
In a custom validator function, how do you access the value of the field being validated?
Question 4
Which built-in validator ensures that a String matches a predefined list of allowed choices?
Question 5
What type of error object is thrown when Mongoose validation fails?

Next Lesson

Pre and Post Middleware Hooks (Document & Query Middleware)

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext