react-hook-form / resolvers

πŸ“‹ Validation resolvers: Yup, Zod, Superstruct, Joi, Vest, Class Validator, io-ts, Nope, computed-types, typanion, Ajv, TypeBox, ArkType, Valibot, effect-ts and VineJS
https://react-hook-form.com/
MIT License
1.67k stars 151 forks source link

Form submission proceeds with empty formValue when validation fails using check (formerly custom) in Valibot #690

Closed yamatohagi closed 1 month ago

yamatohagi commented 1 month ago

Describe the bug When using the check function in Valibot for validation, if validation fails with a case like {isNotify: true, NotifyEmail: ''}, the submit function gets triggered and formValue is lost. This results in submit {} being logged, and the expected behavior is not observed.

To Reproduce 1, Go to the form with Valibot validation. 2, Set isNotify to true and leave NotifyEmail as an empty string. 3, Submit the form. 4, Observe that the form is submitted with an empty formValue and the console logs submit {}.

γ‚Ήγ‚―γƒͺγƒΌγƒ³γ‚·γƒ§γƒƒγƒˆ 2024-06-07 20 18 20

My Codesandbox Include a codesandbox will help us to investigate the issue quicker.

Expected behavior The form should not submit when validation fails, and appropriate error messages should be displayed without losing formValue.

Screenshots

γ‚Ήγ‚―γƒͺγƒΌγƒ³γ‚·γƒ§γƒƒγƒˆ 2024-06-07 20 21 37

Normal time↓

γ‚Ήγ‚―γƒͺγƒΌγƒ³γ‚·γƒ§γƒƒγƒˆ 2024-06-07 20 26 03

Desktop (please complete the following information): all

Smartphone (please complete the following information): all

Additional context I am willing to help fix this bug if guidance on the approach or the codebase is provided. Thank you for your assistance.

yamatohagi commented 1 month ago

//valibot.ts

γ‚Ήγ‚―γƒͺγƒΌγƒ³γ‚·γƒ§γƒƒγƒˆ 2024-06-07 21 04 02

It might be because there is no path.


"NG"
{
    "typed": false,
    "success": false,
    "output": {
        "isCustomerRsvNotify": false,
        "customerRsvNotifyEmail": "la.luce.ymt0326+hoge@gmail.comww",
        "isCustomerCancelNotify": true,
        "customerCancelNotifyEmail": ""
    },
    "issues": [
        {
            "kind": "validation",
            "type": "check",
            "input": {
                "isCustomerRsvNotify": false,
                "customerRsvNotifyEmail": "la.luce.ymt0326+hoge@gmail.comww",
                "isCustomerCancelNotify": true,
                "customerCancelNotifyEmail": ""
            },
            "expected": null,
            "received": "Object",
            "message": "ι€šηŸ₯ε…ˆγƒ‘γƒΌγƒ«γ‚’γƒ‰γƒ¬γ‚Ήγ‚’ε…₯εŠ›γ—γ¦γγ γ•γ„",
            "abortPipeEarly": true
        }
    ]
}

"OK"
{
    "typed": false,
    "success": false,
    "output": {
        "isCustomerRsvNotify": false,
        "customerRsvNotifyEmail": "la.luce.ymt032",
        "isCustomerCancelNotify": false,
        "customerCancelNotifyEmail": ""
    },
    "issues": [
        {
            "kind": "schema",
            "type": "union",
            "input": "la.luce.ymt032",
            "expected": "string | \"\"",
            "received": "\"la.luce.ymt032\"",
            "message": "Invalid type: Expected string | \"\" but received \"la.luce.ymt032\"",
            "path": [
                {
                    "type": "object",
                    "origin": "value",
                    "input": {
                        "isCustomerRsvNotify": false,
                        "customerRsvNotifyEmail": "la.luce.ymt032",
                        "isCustomerCancelNotify": false,
                        "customerCancelNotifyEmail": ""
                    },
                    "key": "customerRsvNotifyEmail",
                    "value": "la.luce.ymt032"
                }
            ],
            "issues": [
                {
                    "kind": "validation",
                    "type": "email",
                    "input": "la.luce.ymt032",
                    "expected": null,
                    "received": "\"la.luce.ymt032\"",
                    "message": "γƒ‘γƒΌγƒ«γ‚’γƒ‰γƒ¬γ‚ΉγŒζ­£γ—γγ‚γ‚ŠγΎγ›γ‚“",
                    "requirement": {},
                    "abortPipeEarly": true
                },
                {
                    "kind": "schema",
                    "type": "literal",
                    "input": "la.luce.ymt032",
                    "expected": "\"\"",
                    "received": "\"la.luce.ymt032\"",
                    "message": "Invalid type: Expected \"\" but received \"la.luce.ymt032\"",
                    "abortPipeEarly": true
                }
            ],
            "abortPipeEarly": true
        }
    ]
}
fabian-hiller commented 1 month ago

This is because the React Hook Form resolver implementation ignores errors that are not related to a nested field (this is the case when getDotPath(issue) returns null). The resolver should add root or unknown errors to a global error message, but I'm not sure if this is supported by React Hook Form. I am happy to fix it, but I need some guidance or hints by the author of React Hook Form.

yamatohagi commented 1 month ago

thank you.

I have resolved the issue on my end. https://github.com/fabian-hiller/valibot/issues/632