Internationalization support with customizable error messages for all validation types and scenarios.
Complete structure for customizing all validation messages.
interface ValidateMessages {
default?: ValidateMessage;
required?: ValidateMessage<[FullField]>;
enum?: ValidateMessage<[FullField, EnumString]>;
whitespace?: ValidateMessage<[FullField]>;
date?: {
format?: ValidateMessage;
parse?: ValidateMessage;
invalid?: ValidateMessage;
};
types?: {
string?: ValidateMessage<[FullField, Type]>;
method?: ValidateMessage<[FullField, Type]>;
array?: ValidateMessage<[FullField, Type]>;
object?: ValidateMessage<[FullField, Type]>;
number?: ValidateMessage<[FullField, Type]>;
date?: ValidateMessage<[FullField, Type]>;
boolean?: ValidateMessage<[FullField, Type]>;
integer?: ValidateMessage<[FullField, Type]>;
float?: ValidateMessage<[FullField, Type]>;
regexp?: ValidateMessage<[FullField, Type]>;
email?: ValidateMessage<[FullField, Type]>;
url?: ValidateMessage<[FullField, Type]>;
hex?: ValidateMessage<[FullField, Type]>;
};
string?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};
number?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};
array?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};
pattern?: {
mismatch?: ValidateMessage<[FullField, Value, Pattern]>;
};
}
type ValidateMessage<T extends any[] = unknown[]> =
| string
| ((...args: T) => string);
interface InternalValidateMessages extends ValidateMessages {
clone: () => InternalValidateMessages;
}Messages can be either static strings or dynamic functions.
type ValidateMessage<T extends any[] = unknown[]> =
| string
| ((...args: T) => string);Usage Examples:
// Static string message
const messages = {
required: "This field is required"
};
// Dynamic function message
const messages = {
required: (field) => `${field} is required`,
string: {
min: (field, min) => `${field} must be at least ${min} characters`
}
};Access and modify default messages through schema instance or static property.
Usage Examples:
// Get current messages
const currentMessages = schema.messages();
// Access default messages statically
const defaultMessages = Schema.messages;
// Set custom messages on schema instance
schema.messages({
required: "This field is mandatory",
types: {
email: "Please enter a valid email address"
}
});The default message templates used by async-validator:
const defaultMessages = {
default: 'Validation error on field %s',
required: '%s is required',
enum: '%s must be one of %s',
whitespace: '%s cannot be empty',
date: {
format: '%s date %s is invalid for format %s',
parse: '%s date could not be parsed, %s is invalid',
invalid: '%s date %s is invalid'
},
types: {
string: '%s is not a %s',
method: '%s is not a %s (function)',
array: '%s is not an %s',
object: '%s is not an %s',
number: '%s is not a %s',
date: '%s is not a %s',
boolean: '%s is not a %s',
integer: '%s is not an %s',
float: '%s is not a %s',
regexp: '%s is not a valid %s',
email: '%s is not a valid %s',
url: '%s is not a valid %s',
hex: '%s is not a valid %s'
},
string: {
len: '%s must be exactly %s characters',
min: '%s must be at least %s characters',
max: '%s cannot be longer than %s characters',
range: '%s must be between %s and %s characters'
},
number: {
len: '%s must equal %s',
min: '%s cannot be less than %s',
max: '%s cannot be greater than %s',
range: '%s must be between %s and %s'
},
array: {
len: '%s must be exactly %s in length',
min: '%s cannot be less than %s in length',
max: '%s cannot be greater than %s in length',
range: '%s must be between %s and %s in length'
},
pattern: {
mismatch: '%s value %s does not match pattern %s'
}
};Create new message instances with the newMessages factory function.
/**
* Create a new messages object with default templates
* @returns Fresh instance of default validation messages
*/
function newMessages(): InternalValidateMessages;Usage Example:
import { newMessages } from "async-validator";
// Create fresh messages instance for customization
const customMessages = newMessages();
customMessages.required = "This field is mandatory";
customMessages.types.email = "Please enter a valid email";
const schema = new Schema(rules);
schema.messages(customMessages);Fallback message for validation errors.
default?: ValidateMessage;Usage Example:
schema.messages({
default: "Validation error occurred"
});Message for required field validation failures.
required?: ValidateMessage<[FullField]>;Usage Examples:
schema.messages({
// Static message
required: "This field is required",
// Dynamic message with field name
required: (field) => `${field} is required`
});Message for enumeration validation failures.
enum?: ValidateMessage<[FullField, EnumString]>;Usage Examples:
schema.messages({
// Static message
enum: "Value must be one of the allowed options",
// Dynamic message with field and enum values
enum: (field, enumValues) => `${field} must be one of: ${enumValues}`
});Message for whitespace-only string validation failures.
whitespace?: ValidateMessage<[FullField]>;Usage Example:
schema.messages({
whitespace: (field) => `${field} cannot be empty or contain only whitespace`
});Messages for type validation failures.
types?: {
string?: ValidateMessage<[FullField, Type]>;
method?: ValidateMessage<[FullField, Type]>;
array?: ValidateMessage<[FullField, Type]>;
object?: ValidateMessage<[FullField, Type]>;
number?: ValidateMessage<[FullField, Type]>;
date?: ValidateMessage<[FullField, Type]>;
boolean?: ValidateMessage<[FullField, Type]>;
integer?: ValidateMessage<[FullField, Type]>;
float?: ValidateMessage<[FullField, Type]>;
regexp?: ValidateMessage<[FullField, Type]>;
email?: ValidateMessage<[FullField, Type]>;
url?: ValidateMessage<[FullField, Type]>;
hex?: ValidateMessage<[FullField, Type]>;
};Usage Examples:
schema.messages({
types: {
string: "Must be text",
number: "Must be a number",
email: "Must be a valid email address",
url: "Must be a valid URL",
array: "Must be a list",
object: "Must be an object",
boolean: "Must be true or false",
date: "Must be a valid date",
// Dynamic messages
integer: (field) => `${field} must be a whole number`,
float: (field) => `${field} must be a decimal number`
}
});Messages for string length validation failures.
string?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};Usage Examples:
schema.messages({
string: {
len: (field, length) => `${field} must be exactly ${length} characters`,
min: (field, min) => `${field} must be at least ${min} characters`,
max: (field, max) => `${field} cannot exceed ${max} characters`,
range: (field, min, max) => `${field} must be between ${min} and ${max} characters`
}
});Messages for number range validation failures.
number?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};Usage Examples:
schema.messages({
number: {
len: (field, value) => `${field} must equal ${value}`,
min: (field, min) => `${field} cannot be less than ${min}`,
max: (field, max) => `${field} cannot be greater than ${max}`,
range: (field, min, max) => `${field} must be between ${min} and ${max}`
}
});Messages for array length validation failures.
array?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};Usage Examples:
schema.messages({
array: {
len: (field, length) => `${field} must contain exactly ${length} items`,
min: (field, min) => `${field} must contain at least ${min} items`,
max: (field, max) => `${field} cannot contain more than ${max} items`,
range: (field, min, max) => `${field} must contain between ${min} and ${max} items`
}
});Messages for pattern matching validation failures.
pattern?: {
mismatch?: ValidateMessage<[FullField, Value, Pattern]>;
};Usage Example:
schema.messages({
pattern: {
mismatch: (field, value, pattern) =>
`${field} value "${value}" does not match required pattern ${pattern}`
}
});Messages for date validation failures.
date?: {
format?: ValidateMessage;
parse?: ValidateMessage;
invalid?: ValidateMessage;
};Usage Examples:
schema.messages({
date: {
format: "Date format is invalid",
parse: "Date could not be parsed",
invalid: "Date is invalid",
// Dynamic messages
format: (field, date, format) => `${field} date ${date} is invalid for format ${format}`,
parse: (field, date) => `${field} date could not be parsed, ${date} is invalid`,
invalid: (field, date) => `${field} date ${date} is invalid`
}
});const englishMessages = {
required: (field) => `${field} is required`,
types: {
string: (field) => `${field} must be text`,
number: (field) => `${field} must be a number`,
email: (field) => `${field} must be a valid email address`
},
string: {
min: (field, min) => `${field} must be at least ${min} characters`,
max: (field, max) => `${field} cannot exceed ${max} characters`
}
};
schema.messages(englishMessages);const spanishMessages = {
required: (field) => `${field} es requerido`,
types: {
string: (field) => `${field} debe ser texto`,
number: (field) => `${field} debe ser un número`,
email: (field) => `${field} debe ser una dirección de email válida`
},
string: {
min: (field, min) => `${field} debe tener al menos ${min} caracteres`,
max: (field, max) => `${field} no puede exceder ${max} caracteres`
}
};
schema.messages(spanishMessages);const frenchMessages = {
required: (field) => `${field} est requis`,
types: {
string: (field) => `${field} doit être du texte`,
number: (field) => `${field} doit être un nombre`,
email: (field) => `${field} doit être une adresse email valide`
},
string: {
min: (field, min) => `${field} doit avoir au moins ${min} caractères`,
max: (field, max) => `${field} ne peut pas dépasser ${max} caractères`
}
};
schema.messages(frenchMessages);Override messages during specific validation calls.
Usage Examples:
// Override messages for specific validation
await schema.validate(data, {
messages: {
required: "Please fill in this field",
types: {
email: "Please enter a valid email"
}
}
});
// Combine global and local messages
schema.messages({
required: "This field is required"
});
await schema.validate(data, {
messages: {
types: {
email: "Email format is incorrect" // Specific override
}
}
});Create independent message copies and merge configurations.
Usage Examples:
// Clone default messages for customization
const customMessages = Schema.messages.clone();
customMessages.required = "Field is mandatory";
// Create new schema with custom messages
const schema = new Schema(rules);
schema.messages(customMessages);
// Deep merge messages
const baseMessages = {
required: "Required field",
types: { string: "Must be text" }
};
const additionalMessages = {
types: { number: "Must be numeric" },
string: { min: "Too short" }
};
// Merge configurations
schema.messages({ ...baseMessages, ...additionalMessages });Override messages at the individual rule level.
Usage Example:
const rules = {
username: {
type: "string",
required: true,
min: 3,
message: "Username must be at least 3 characters and is required"
},
email: [
{ type: "email", message: "Please enter a valid email address" },
{ required: true, message: "Email is required" }
],
age: {
type: "number",
min: 18,
message: (field) => `${field} must be 18 or older`
}
};