createMessageBuilder
The createMessageBuilder function is the core string-formatting engine of zod-validation-error. It takes raw Zod issues and combines them into a polished, final string.
Philosophy: ErrorMap vs MessageBuilder
It is important to understand the pipeline:
- Error Map: Formats individual issues (e.g., translates
too_smallinto"Number must be greater than 0"). - Message Builder: Takes that array of formatted strings, adds paths (e.g.,
at "user.age"), joins them together with separators (e.g.,;), and prepends a prefix.
Signature
type MessageBuilder = (issues: NonEmptyArray<ZodIssue>) => string;
function createMessageBuilder(
partialOptions?: Partial<MessageBuilderOptions>
): MessageBuilder
Configuration Options (MessageBuilderOptions)
You can pass these options to createMessageBuilder directly, or you can pass them in the options argument of fromError and fromZodError (which creates a Message Builder under the hood).
| Option | Type | Default | Description |
|---|---|---|---|
maxIssuesInMessage |
number |
99 |
The maximum number of issues to display before truncating. |
issueSeparator |
string |
"; " |
The string used to join multiple distinct issues. |
unionSeparator |
string |
" or " |
The string used to join issues arising from zod.union failures. |
prefix |
string | null |
"Validation error" |
The prefix appended to the very front of the error message. Pass null to disable completely. |
prefixSeparator |
string |
": " |
The string joining the prefix to the first issue (ignored if prefix is null). |
includePath |
boolean |
true |
Whether to include the property path (e.g., at "user.name") in the message. |
forceTitleCase |
boolean |
true |
Whether to capitalize the first letter of every individual issue message. |
Examples
Standard Customization via fromError
Usually, you don't need to call createMessageBuilder directly. You pass its options to fromError:
import { fromError } from 'zod-validation-error';
const err = fromError(zodError, {
prefix: 'Form Submission Failed',
issueSeparator: '\n - ',
includePath: false, // Don't show technical paths to the user
});
// Output:
// Form Submission Failed:
// - Invalid email address
// - String must contain at least 5 character(s)
Creating a Fully Custom Message Builder
If the configuration options aren't enough, you can bypass createMessageBuilder entirely and write your own MessageBuilder function from scratch.
This is useful if you want to implement syntax highlighting (e.g., via chalk) for CLI tools.
import { z as zod } from 'zod';
import { type MessageBuilder, fromError } from 'zod-validation-error';
import chalk from 'chalk';
// Write a completely custom builder
const myMessageBuilder: MessageBuilder = (issues) => {
return issues
.map((issue) => {
// Colorize the path in yellow, and the message in red
const path = issue.path.join('.');
return `${chalk.yellow(path)}: ${chalk.red(issue.message)}`;
})
.join('\n');
};
const schema = zod.object({ email: zod.email() });
const result = schema.safeParse({ email: 'bad' });
if (!result.success) {
const validationError = fromError(result.error, {
// Inject your custom builder
messageBuilder: myMessageBuilder,
});
console.log(validationError.toString());
}