Debugging validation issues between react-hook-form and zod
When using react-hook-form with zod via zodResolver
you might run into a problem where your form won’t validate and you don’t know why - no error is thrown, no log messages written, but formState.isValid
never shows true
.
Here’s the tip: If you are using defaultValues
with useForm
then your zod schema needs to be able to validate defaultValues
. If it fails to validate then you won’t know why, your form will just stay invalid. But you can test in your code:
const {
handleSubmit,
control,
formState: { isDirty, isValid, errors },
} = useForm({
defaultValues,
resolver: zodResolver(zFormSchema),
mode: "onBlur",
});
// Directly parse defaultValues to surface a parsing error.
// I recommend leaving this in the code, that way if the schema
// and defaultValues diverge you will know right away
// (a softer alternative is to use safeParse and log the issue,
// but then your form is probably silently broken)
zFormSchema.parse(defaultValues);
This doesn’t cover every possibility (eg if you’re doing something custom with .transform
then your defaultValues
might not hit it) but in general defaultValues
is coming from your DB, so is presumed to be valid. This has helped me debug a few validation issues with react-hook-form and zod.