zod
zod copied to clipboard
Ability to add label to be shown in error instead of generic like: String must contain at least 3 character(s)
For example if I have this validation
const schema = z.object({
firstName: z.string().min(3).max(12),
isActive: z.boolean(),
role: z.enum(['Admin', 'User']),
});
const result = schema.safeParse({
"firstName": '',
"isActive": null,
"role": "min",
});
console.log(JSON.stringify(result, null, 2));
{
"success": false,
"error": {
"issues": [
{
"code": "too_small",
"minimum": 3,
"type": "string",
"inclusive": true,
"message": "String must contain at least 3 character(s)",
"path": [
"firstName"
]
},
{
"code": "invalid_type",
"expected": "boolean",
"received": "null",
"path": [
"isActive"
],
"message": "Expected boolean, received null"
},
{
"received": "min",
"code": "invalid_enum_value",
"options": [
"Admin",
"User"
],
"path": [
"role"
],
"message": "Invalid enum value. Expected 'Admin' | 'User', received 'min'"
}
],
"name": "ZodError"
}
}
Error message will be
firstName must contain at least 3 character(s)
instead of String must contain at least 3 character(s)
Just for clarification
z.string().min(3, 'String is too short')
or
z.string().min(3,{ message: 'String is too short' })
Incorrect
schema.parse(''); // String must contain at least 3 character(s)
schema.parse('12'); // String must contain at least 3 character(s)
Correct:
schema.parse(undefined); // String is too short
It is probably bug because when I use undefined string it will use correct error message with min() function. Problem is only with defined short strings
yup has a method called .label()
that you can use to replace the String
part in the error message.
I wish zod has something like that
yup has a method called
.label()
that you can use to replace theString
part in the error message. I wish zod has something like that
I'm coming from yup and missing the .label()
feature. With that, the error message is more readable to the user without us giving a custom error message for every single type validation.
Agree, this is badly needed, it's bad ux not to name the field/label in the error message.
i think by default it should use the field name, and also have a convenient override like label().
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
no, no stalebot...
Is there an issue with using path
here? I don't think there is a default message we can use that will satisfy all use cases since Zod is not a form-validation library but rather a runtime type system with lots of different use cases.
so it seems like you're asking why users can't just use path
as alluded to in the ERROR_HANDLING docs. There is also this package as another option.
IIRC, (i haven't used any of this in 2 months) I think some of us just didn't see why manual customization/workaround or another package should be necessary to use path by default and preferably even a label() option. If it needs to stay hard-coded with a generic type label for other use cases, then that's understandable.
If what i have listed above is the stance of devs, than maybe closing as wontfix
, optionally with a brief explanation, would be preferable to the stalebot being unleashed, which i find to be a somewhat disagreeable way to close an issue. :)
thanks
If what i have listed above is the stance of devs, than maybe closing as wontfix, optionally with a brief explanation, would be preferable to the stalebot being unleashed, which i find to be a somewhat disagreeable way to close an issue. :)
Thanks for being candid with you feedback. That's a fair stance and I know stalebot is a bit of a controversial approach to issue management. I wish we had a bit more time to spend on community engagement and issue triage, but for me personally, it's an occasional thing that I help out with. Giving thoughtful feedback to every issue and curating suggestions as they age is definitely a time-consuming job for a popular library, as I'm sure you can imagine. 😅 I'll close this issue for now and take note of this friction. We definitely appreciate the time and attention everyone has given here.
I think some of us just didn't see why manual customization/workaround or another package should be necessary to use path by default and preferably even a label() option. If it needs to stay hard-coded with a generic type label for other use cases, then that's understandable.
I don't speak for @colinhacks who is usually the arbiter of the general vision and direction of the API and larger architectural decisions, but I think this is not likely to be a direction we go on our own, especially when most usage of Zod with forms is mediated by a form library.
Folks coming from object/form validation libraries like Yup definitely miss some of the nicer features that focus on that specific use case, and I sympathize with wanting a more batteries-included experience. I do think that experience belongs in a tool that utilizes Zod, rather than in Zod itself which is very focused on "runtime type system" rather than validation or any specific use case.
I think in general, we're trying to be careful with how much surface area the core Zod package has since we have to balance ergonomics for a certain use case against complexity, ease of understanding, ease of maintenance, and speed. This is especially true of parsing objects which has been something we've had to try really hard to get performance up on so every allocation and conditional is something we have to be very careful about. Concretely, schemas are embedded in other schemas, so a string schema doesn't even know it's own path, so the error handling would need to be refactored pretty substantially for a feature like this to be done right with a mind to general performance and complexity.