Search code examples
typescriptzod

How do I change Zod's array custom error?


I am using Zod to validate my react-hook-form fields and I keep getting the predefined error of "Expected array, received null", but I want a more front-end friendly wording that I define. How do I set a custom message for this setup? See promos below, with corresponding output when submitted with no selections made to the "checkbox" array field..

Code:

    promotion: z.object({
        id: z.string().optional(),
        name: z.string({
                required_error: "A name is required.",
                invalid_type_error: "A name is required.",
            }).min(1, "A name is required.").max(150, "The name must be less than 150 characters."),
        email: z.string({
                required_error: "An email is required.",
                invalid_type_error: "This is an invalid email.",
            }).email().min(1, "An email is required."),
        promos: z.array( z.string({
                required_error: "A promotion selection is required.",
                invalid_type_error: "This is an invalid promotion selection",
            }).min(1, "A promotion selection is required.") ).min(1, "At least one promotion selection is required."),
    }),

Output:

enter image description here


Solution

  • You can set a global custom ZodErrorMap in order to handle specific kind of issue behavior. The scope is global.

    import { z } from "zod";
    
    const customErrorMap: z.ZodErrorMap = (issue, ctx) => {
      if (issue.code === z.ZodIssueCode.invalid_type) {
        if (issue.expected === "string") {
          return { message: "bad type!" };
        }
      }
      if (issue.code === z.ZodIssueCode.custom) {
        return { message: `less-than-${(issue.params || {}).minimum}` };
      }
      return { message: ctx.defaultError };
    };
    
    z.setErrorMap(customErrorMap);
    

    https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md#customizing-errors-with-zoderrormap

    If you want less generic usage, you can apply the customized ZodErrorMap to the schema definition or on the schema parsing callback. But for schema application I think not all schema supports customized ZodErrorMap param.

    UPDATED 2023-01-25

    Try using the following

    z.setErrorMap((issue, ctx) => {
      if (issue.code === "invalid_type" && issue.expected === "array")
        return { message: "Your array is not well defined" };
      return { message: ctx.defaultError };
    });