resolvers icon indicating copy to clipboard operation
resolvers copied to clipboard

issue: Root error messages returned from schema are immediately removed during form submit

Open solomonhawk opened this issue 2 years ago • 4 comments

Version Number

7.43.9

Codesandbox/Expo snack

https://codesandbox.io/s/react-hook-form-zod-root-error-je3yve?file=/src/App.tsx

Discord Question Thread link

https://discord.com/channels/754891658327359538/1108113385968644217/1108113385968644217

Steps to reproduce

This issue relates to and is observed when using [email protected] and @hookform/[email protected] and using a zod schema resolver with useForm.

  1. Go to 'the sandbox'
  2. Read the summary/instructions therein, or keep reading here
  3. Open the Console inside the sandbox
  4. Click on "Submit"
  5. Despite the form being invalid, it is submitted (the submit handler is called with {} which is invalid data)
  6. Find the place in the schema where the path of the custom global error is specified and change it from ["root", "global"] to just ["global"]
  7. Submit the form again, it should fail validation and display the global error message

Longer explanation of the problem

Copied from within the sandbox:

This example demonstrates an issue with assigning errors to "root." (global form errors) from within a zod schema. There are 2 different issues that can be observed.

  1. If the schema contains only errors on "root." keys, then the form is considered valid (it should be invalid). You can observe this by submitting the form - the onSubmit callback is called but with an empty object, which should not be valid.

  2. Errors on "root." are removed from the form state during submission, so they cannot be seen in the UI. This happens here during submission but after the schema is executed which means any root errors added by the schema for this submission are immediately removed.

If you uncomment L41 and comment out L44, so that the schema appends an error to "global" instead of "root.global", you will observe that this error 1) prevents the submission from being considered valid and 2) displays in the UI because it isn't stripped during submission.

If you click the "Set Error" button, you can see that manually calling setError with a "root." key does insert the error properly outside of submit.

Expected behaviour

Error messages under the "root.<field>" namespace returned from the provided schema during submission should exist in the form error state at least until the next submission.

What browsers are you seeing the problem on?

Firefox, Chrome, Safari, Edge

Suggested Fix

I'm not super familiar with the codebase, so take this with a grain of salt...

Move unset(_formState.errors, 'root') above where we call const { errors, values } = await _executeSchema();. (related code)

Relevant log output

No response

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct

solomonhawk avatar May 16 '23 20:05 solomonhawk

we do not support root error messages for schema at the moment.

bluebill1049 avatar May 16 '23 22:05 bluebill1049

Thanks for chiming in so quickly, appreciate the time and effort you and others put in to maintain this library. 🙏

What does support for root error messages in schemas involve, all together? Are there other unwanted side effects that would be caused by moving the root error unsetting during submission to before the schema execution? It seems, at first blush, that this would at least open the door for schemas to set root errors (I think it's the only thing currently preventing this from working in my particular case).

Is there a place in the docs where this might be clarified? I'm happy to contribute.

solomonhawk avatar May 16 '23 23:05 solomonhawk

The weird thing is that this all almost works fine if I just don't prefix the "global" error with root. - I'm able to set these errors in the schema and display them in the form. It's basically like adding an error that is not associated with a registered input. The only trouble is the TS definitions for calling setError and so forth which allow for "root." prefixes and keys in the FieldValues but nothing else.

solomonhawk avatar May 17 '23 17:05 solomonhawk

What does support for root error messages in schemas involve, all together? Are there other unwanted side effects that would be caused by moving the root error unsetting during submission to before the schema execution? It seems, at first blush, that this would at least open the door for schemas to set root errors (I think it's the only thing currently preventing this from working in my particular case).

I think this is something we want to support, as root errors are used for field array errors. https://github.com/react-hook-form/react-hook-form/releases/tag/v7.44.0-next.0

bluebill1049 avatar May 18 '23 08:05 bluebill1049