zod icon indicating copy to clipboard operation
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)

Open laminekalinko2 opened this issue 2 years ago • 6 comments

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)

laminekalinko2 avatar May 19 '22 23:05 laminekalinko2

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

seeden avatar May 21 '22 19:05 seeden

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

seeden avatar May 21 '22 19:05 seeden

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

waptik avatar Jun 26 '22 18:06 waptik

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

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.

riolly avatar Aug 03 '22 02:08 riolly

Agree, this is badly needed, it's bad ux not to name the field/label in the error message.

Zerebokep avatar Aug 11 '22 12:08 Zerebokep

i think by default it should use the field name, and also have a convenient override like label().

ITwrx avatar Aug 13 '22 02:08 ITwrx

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.

stale[bot] avatar Oct 12 '22 18:10 stale[bot]

no, no stalebot...

ITwrx avatar Oct 12 '22 19:10 ITwrx

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.

scotttrinh avatar Oct 12 '22 20:10 scotttrinh

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

ITwrx avatar Oct 12 '22 21:10 ITwrx

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.

scotttrinh avatar Oct 13 '22 01:10 scotttrinh