ITADN

Improve Default Validation Messages for Forms and APIs

#1453Openheiwen 创建于 2026-04-14
enhancement
H
heiwencommented
## 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 条评论