Improve Default Validation Messages for Forms and APIs
enhancement
## 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:
- `Age is required`
### Invalid type
Instead of:
- `Invalid type: Expected number but received "17"`
Prefer:
- `Age must be a number`
### 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:
- debug
- form
- api
- agent
But that is not required for this ticket. The immediate ask is only to improve the default `message` strings while preserving the existing structure.
0 条评论