Summary
Valibot's current issue objects contain enough structural detail for forms, APIs, and agentic tooling, but the default message strings are still mostly validator-facing rather than user-facing.
In practice, this means application code often has to override or remap the default message for nearly every field before showing validation feedback in a UI. That creates repetitive boilerplate, increases maintenance cost, and reduces the value of having strong built-in defaults in the first place.
This ticket proposes improving the default message generation only, while keeping the existing issue/output structure unchanged.
Problem
Today, Valibot messages are technically correct, but many of them are not ideal as defaults for:
- form field errors shown directly to end users
- API validation responses consumed by frontend clients
- agent/tooling workflows that benefit from cleaner semantic phrasing
Examples of current messages:
Invalid key: Expected "age" but received undefined
Invalid type: Expected number but received "17"
Invalid length: Expected >=8 but received 3
Invalid email: Received ""
These messages expose implementation details and validator terminology:
expected / received
- quoted raw values
undefined
Invalid key
- constraint syntax such as
>=8
That wording is useful for debugging, but weak as a default for user-facing validation.
Goal
Improve the default message values so they are more friendly for forms and APIs, without changing:
- issue object shape
- path structure
kind
type
expected
received
- nested
issues
This is a message-quality improvement, not a schema/result-shape redesign.
Non-Goals
- Do not change the current issue structure.
- Do not remove existing metadata such as
expected, received, input, or path.
- Do not require a new formatter API for the initial improvement.
- Do not reduce debugging detail outside of the
message field.
Why This Matters
Valibot already has strong primitives:
- detailed issue metadata
- structured paths
flatten(...)
summarize(...)
The main gap is the wording of default messages. Improving only message would make Valibot much more usable out of the box for:
- direct form field rendering
- API validation responses
- generic client-side error mappers
Proposed Direction
Keep the same issue objects, but revise the default message generation to be more semantic and less diagnostic.
Examples:
| Current message |
Better default message |
Invalid key: Expected "age" but received undefined |
Age is required |
Invalid key: Expected "website" but received undefined |
Website is required |
Invalid type: Expected number but received "17" |
Age must be a number |
Invalid type: Expected ("admin" | "member") but received "boss" |
Role must be one of: admin, member |
Invalid length: Expected >=8 but received 3 |
Password must be at least 8 characters |
Invalid email: Received "not-an-email" |
Enter a valid email address |
Invalid URL: Received "wat" |
Enter a valid URL |
Suggested Message Rules
Required / missing keys
Current missing-key messages are the weakest part of the UX.
Instead of:
Invalid key: Expected "age" but received undefined
Prefer:
Invalid type
Instead of:
Invalid type: Expected number but received "17"
Prefer:
Invalid format
Instead of:
Invalid email: Received "foo"
Invalid URL: Received "wat"
Prefer:
Enter a valid email address
Enter a valid URL
Length / size constraints
Instead of:
Invalid length: Expected >=8 but received 3
Prefer:
Password must be at least 8 characters
Desired Outcome
After this change, consumers who directly surface issue.message should get defaults that are:
- safer to show to users
- less diagnostic/noisy
- more consistent across validators
- easier to use in forms without custom per-field copy
Advanced consumers would still retain full access to:
type
expected
received
path
- nested issue metadata
Acceptance Criteria
- Default Valibot messages are more user-facing for common validation failures.
- Missing required object keys no longer default to
Invalid key: Expected ... received undefined.
- Common formats like email and URL use friendlier wording.
- Type mismatch messages avoid overly diagnostic phrasing by default.
- Issue/result object shape remains unchanged.
- Existing metadata fields remain available for advanced formatting/debugging.
Optional Follow-Up
Once the default messages are improved, Valibot could optionally add presets later such as:
But that is not required for this ticket. The immediate ask is only to improve the default message strings while preserving the existing structure.
Summary
Valibot's current issue objects contain enough structural detail for forms, APIs, and agentic tooling, but the default
messagestrings are still mostly validator-facing rather than user-facing.In practice, this means application code often has to override or remap the default message for nearly every field before showing validation feedback in a UI. That creates repetitive boilerplate, increases maintenance cost, and reduces the value of having strong built-in defaults in the first place.
This ticket proposes improving the default
messagegeneration only, while keeping the existing issue/output structure unchanged.Problem
Today, Valibot messages are technically correct, but many of them are not ideal as defaults for:
Examples of current messages:
Invalid key: Expected "age" but received undefinedInvalid type: Expected number but received "17"Invalid length: Expected >=8 but received 3Invalid email: Received ""These messages expose implementation details and validator terminology:
expected/receivedundefinedInvalid key>=8That wording is useful for debugging, but weak as a default for user-facing validation.
Goal
Improve the default
messagevalues so they are more friendly for forms and APIs, without changing:kindtypeexpectedreceivedissuesThis is a message-quality improvement, not a schema/result-shape redesign.
Non-Goals
expected,received,input, orpath.messagefield.Why This Matters
Valibot already has strong primitives:
flatten(...)summarize(...)The main gap is the wording of default messages. Improving only
messagewould make Valibot much more usable out of the box for:Proposed Direction
Keep the same issue objects, but revise the default
messagegeneration to be more semantic and less diagnostic.Examples:
Invalid key: Expected "age" but received undefinedAge is requiredInvalid key: Expected "website" but received undefinedWebsite is requiredInvalid type: Expected number but received "17"Age must be a numberInvalid type: Expected ("admin" | "member") but received "boss"Role must be one of: admin, memberInvalid length: Expected >=8 but received 3Password must be at least 8 charactersInvalid email: Received "not-an-email"Enter a valid email addressInvalid URL: Received "wat"Enter a valid URLSuggested Message Rules
Required / missing keys
Current missing-key messages are the weakest part of the UX.
Instead of:
Invalid key: Expected "age" but received undefinedPrefer:
Age is requiredInvalid type
Instead of:
Invalid type: Expected number but received "17"Prefer:
Age must be a numberInvalid format
Instead of:
Invalid email: Received "foo"Invalid URL: Received "wat"Prefer:
Enter a valid email addressEnter a valid URLLength / size constraints
Instead of:
Invalid length: Expected >=8 but received 3Prefer:
Password must be at least 8 charactersDesired Outcome
After this change, consumers who directly surface
issue.messageshould get defaults that are:Advanced consumers would still retain full access to:
typeexpectedreceivedpathAcceptance Criteria
Invalid key: Expected ... received undefined.Optional Follow-Up
Once the default messages are improved, Valibot could optionally add presets later such as:
But that is not required for this ticket. The immediate ask is only to improve the default
messagestrings while preserving the existing structure.