zod
zod copied to clipboard
Type instantiation is excessively deep and possibly infinite" when using Zod with React Hook Form and @hookform/resolvers
Zod 3.25.20 Typescript 5.7 "turbo": "^2.5.3",
i am receiving Type instantiation is excessively deep and possibly infinite.ts(2589) (alias) zodResolver<any, any, any>(schema: any, schemaOptions?: Partial<ParseParams>, resolverOptions?: { mode?: "async" | "sync"; raw?: false; }): Resolver<any, any, any> (+1 overload) import zodResolver import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage, } from "./form";
import { Input } from "./input"; import { Button } from "./button";
const formSchema = z.object({ name: z.string().min(2, { message: "İsim en az 2 karakter olmalı" }), email: z.string().email({ message: "Geçerli bir e-posta girin" }), }); type FormSchema = { name: string; email: string; };
export default function UserForm() { const form = useForm<FormSchema>({ resolver: zodResolver(formSchema), defaultValues: { name: "", email: "", }, });
const onSubmit = (values: FormSchema) => { console.log("Form gönderildi:", values); };
return ( <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)} className="max-w-md space-y-4" > <FormField control={form.control} name="name" render={({ field }) => ( <FormItem> <FormLabel>İsim</FormLabel> <FormControl> <Input placeholder="Adınızı girin" {...field} /> </FormControl> <FormMessage /> </FormItem> )} />
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input
type="email"
placeholder="E-posta adresinizi girin"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Gönder</Button>
</form>
</Form>
); }
Can you create a reproduction repo? There are too many other moving parts (config files, dependency resolution) for me to reproduce with the information provided.
@ahmettavsan can you please try to install versions 3.25.7 and 3.25.8 and tell me if you start having this with version 3.25.8 ?
👋🏼 I ran into the same error while working on https://github.com/vercel/ai/pull/6421. I upgraded to [email protected]
I created a minimal test case to reproduce the error
import * as z3 from 'zod/v3';
import * as z4 from 'zod/v4/core';
import { z } from 'zod/v4'
export function test<
RESULT extends SCHEMA extends z4.$ZodType
? z4.infer<SCHEMA>
: SCHEMA extends z3.Schema
? z3.infer<SCHEMA>
// ^ Type instantiation is excessively deep and possibly infinite
: never,
SCHEMA extends z3.Schema | z4.$ZodType,
>(
schema: SCHEMA,
): RESULT {
return {} as unknown as RESULT;
}
const schema = z.object({ foo: z.string()})
const funk = test(schema)
const testString: string = funk.foo
const yo: z4.infer<typeof schema> = {
foo: 'yo'
}
Update
slightly simpler test case
import * as z3 from 'zod/v3';
import * as z4 from 'zod/v4/core';
export function test<
RESULT extends SCHEMA extends z3.Schema
? z3.infer<SCHEMA>
// ^ Type instantiation is excessively deep and possibly infinite
: never,
SCHEMA extends z3.Schema | z4.$ZodType,
>(
schema: SCHEMA,
): RESULT {
return {} as unknown as RESULT;
}
const schema = z3.z.object({ foo: z3.z.string()})
const funk = test(schema)
const testString: string = funk.foo
If I replace SCHEMA extends z3.Schema | z4.$ZodType with just SCHEMA extends z3.Schema then the error goes away, so it has something to do that with the fact that type can be either a z3 or z4 type
The error also goes away when doing SCHEMA extends z4.$ZodType ? z4.infer<SCHEMA> instead of using the z3 APIs in the example above. So there must be something that z4.infer does that z3.infer doesn't?
full example using z4 APIs
import * as z3 from 'zod/v3';
import * as z4 from 'zod/v4/core';
import { z } from 'zod/v4';
export function test<
RESULT extends SCHEMA extends z4.$ZodType
? z4.infer<SCHEMA>
: never,
SCHEMA extends z4.$ZodType | z3.Schema,
>(
schema: SCHEMA,
): RESULT {
return {} as unknown as RESULT;
}
const schema = z.object({ foo: z.string()})
const funk = test(schema)
const testString: string = funk.foo
@OscarCornish figured out the problem of the "Type instantiation is excessively deep and possibly infinite" error in my test case above. It's not a bug with zod.
I think it's because you are defining RESULT before SCHEMA, even though it depends on schema, which is triggering re-evaluation
Here is the working code for reference: playground link
import * as z3 from 'zod/v3';
import * as z4 from 'zod/v4/core';
type InferSchema<S> =
S extends z3.Schema ? z3.infer<S> :
S extends z4.$ZodType ? z4.infer<S> :
never;
export function test<
SCHEMA extends z3.Schema | z4.$ZodType,
RESULT = InferSchema<SCHEMA>
>(
schema: SCHEMA,
): RESULT {
return {} as unknown as RESULT;
}
const schema = z3.z.object({ foo: z3.z.string()})
const funk = test(schema)
const testString: string = funk.foo
Sorry for the noise, feel free to hide my comments as off topic or resolved.
I'm not able to reproduce the original issue with the information provided. Reproductions should be self-contained.
It's very likely this is fixed in recent versions, which contain changes to mitigate "Excessively deep" errors.
Zod 4 support for RHF can be tracked here: https://github.com/react-hook-form/resolvers/pull/776
cc @gr2m Both of your original problem cases now work with [email protected] (and possible earlier versions).
cc @ahmettavsan for future reference use triple backticks to contain code blocks in issues
```ts
// typescript code here
```
cc @gr2m Both of your original problem cases now work with
[email protected](and possible earlier versions).
yes, confirmed! Thanks for all your great work @colinhacks!