colinhacks / zod

TypeScript-first schema validation with static type inference

Home Page:https://zod.dev

Repository from Github https://github.comcolinhacks/zodRepository from Github https://github.comcolinhacks/zod

"Type instantiation is excessively deep and possibly infinite" when using Zod with React Hook Form and @hookform/resolvers

jaus14 opened this issue · comments

When using zod, react-hook-form, and @hookform/resolvers, I encountered a TypeScript error:

Type instantiation is excessively deep and possibly infinite.

This happens when defining a schema with Zod and passing it to @hookform/resolvers/zod.

Steps to Reproduce

  1. Define a schema:
    import { z } from "zod";
    
    const FormSchema = z.object({
      name: z.string(),
      loginId: z.string(),
      password: z.string(),
    })
  2. Use it in useForm:
    import { useForm } from "react-hook-form";
    import { zodResolver } from "@hookform/resolvers/zod";
    
    const form = useFormz.infer<typeof FormSchema>>({
      resolver: zodResolver(schema),
    });
  3. TypeScript throws an error:
    Type instantiation is excessively deep and possibly infinite.
    
Image Image

I fix it by downgrading Zod

  • Downgrading Zod from 3.42.2 to 3.42.1 resolved the issue.

Environment

  • TypeScript: 5.3.3
  • Zod: 3.42.2
  • React Hook Form: 7.54.2
  • @hookform/resolvers: 3.10.0

Running into the exact same issue

I can confirm, the problems start yesterday, after upgrading from 3.24.1 to 3.24.2, downgrading solves the problem!

commented

Confirmed as well. Downgrading patch solved the issue for me.

Same issue!

In Turborepo we have a shared package which exports Schemas. Using the zodResolver(schema) I received an error "Type instantiation is excessively deep and possibly infinite" - Fixed by downgrading from zod@3.24.3 to zod@3.24.2 and restart TS server.

@taylor-lindores-reeves thanks. Unfortunately the most minor patches often cause issues like that with zod.

Thanks. The problem occurs when I use version 3.24.3.

If you use yarn you can use yarn why zod to investigate.
I found out that my issue was a mismatch between zod versions accross dependencies.
I had to add "resolutions": {"zod": "<version_number>"} to my package.json to fix this.

My take is that external libraries should always be using zod as a peerDependency to avoid such conflicts.

I have been using the zod version 3.23.8 and react-hook-form 7.51.5 for a while to not have this problem. However, when we attempt to update to nextjs 15 and react 19, we HAVE to update react-hook-form and thus run into this problem again.

Just like the simple schema of the OP, my schema is just:

const FormSchema = z.object({
  items: z.array(z.string()),
});

Which shouldn't be excessively deep and possibly infinite. Is there really no way to tell react hook form that he should just swallow this message as a warning?

Running into the exact same issue

If you use yarn you can use yarn why zod to investigate. I found out that my issue was a mismatch between zod versions accross dependencies. I had to add "resolutions": {"zod": "<version_number>"} to my package.json to fix this.

My take is that external libraries should always be using zod as a peerDependency to avoid such conflicts.

Thank you! @yleflour This solution works for me!

In our case it was a conflict of versions (we had 3.42.3 pinned but some eslint dependency brought 3.42.4). Bumping pinned version to 3.24.4 resolved the issue).

In case of pnpm running pnpm why zod will show what versions of zod are present.

also fixed it by downgrading to 3.24.2. No nerves to investigate more at this point.

For me, downgrading to @hookform/resolvers@4.1.3 did the trick

This works for me:

  • Zod: 3.24.2
  • React Hook Form: 7.54.2
  • @hookform/resolvers: 4.1.3

The same issue here and package versions from @QuocZuong does not help :( Any suggestions?

The same issue here and package versions from @QuocZuong does not help :( Any suggestions?

Just to be sure, have you deleted node_modules, package-lock, and npm cache?

Actually I need a react-hook-form ^7.57.0 to have subscription method. My packages are:

    "react-hook-form": "^7.57.0",
    "@hookform/resolvers": "^3.4.2",
    "zod": "^3.23.8"

I didnt remove package-lock beacuse I dont want to update my other packages (but I remove cache and node_modules). Now I switched to using FormProvider instead of passing control and errors to my form components and majority of errors disappeared but still some occurs when I use typed context. Here is the example:

  const { watch, trigger, control, setValue } =
    useFormContext<HomeworkSchemaType>();

  const {
    fields: answers,
    append,
    remove,
  } = useFieldArray({
    control,
    name: `exams.${index}.answers`,
  });

  const exam = watch(`exams.${index}`);

and using that watch is the reason of that error. Somilarly in other componets I use setValue and the error occurs:

 const schema = z.object({
    src: z
      .string()
      .optional()
      .refine((value) => !value || validateLink(value), {
        message: 'Nieprawidłowy link',
      }),
    file: file,
  });

  type SchemaType = z.infer<typeof schema>;

  const form = useForm<SchemaType>({
    resolver: zodResolver(schema),
    mode: 'all',
  });

  const {
    watch,
    handleSubmit,
    setFocus,
    setValue,
    trigger,
    formState: { isValid },
  } = form;

// on click handler in some component:
  setValue('file', toUploaderFile(res));

OK, the issue was with my custom schema like this:

export const file = z
  .custom<UploaderFile>()
  .refine((file) => {
    if (file?.uploading) return false;
    if (file?.id) return true;
  }, 'Plik jest wymagany');


where


export type UploaderFile = {
  file?: globalThis.File;
  src: string;
  extension: DefaultExtensionType;
  progress?: number;
  uploading?: boolean;
  name: string;
  size: number;
  id?: string;
  uploadedFile?: UploadedFile;
  controller?: AbortController;
};

I defined schema using z.object() and now it works :)

Still got the issue, does someone have a fix ?