yup: TypeError: Cannot read property 'fulfilled' of undefined
Describe the bug I have a Codesandbox running a library called React Hook Form. If you add two friends in the code pen and then remove the first friend and then submit the form you see the error. The stack trace shows the error at a line in react-hook-form.js. BUT if you dig deeper the error is actually coming from line 84 of runValidations.js where the check for !r.fulfilled throws an error saying:
"TypeError: Cannot read property 'fulfilled' of undefined at eval (eval at <anonymous> (https://yycrz.csb.app/node_modules/yup/lib/util/runValidations.js), <anonymous>:1:3) at eval (https://yycrz.csb.app/node_modules/yup/lib/util/runValidations.js:84:17) at Array.filter (<anonymous>) at eval (https://yycrz.csb.app/node_modules/yup/lib/util/runValidations.js:83:32) at async Promise.all (index 0) at async validateWithSchema (https://yycrz.csb.app/node_modules/react-hook-form/dist/react-hook-form.js:383:21) at async eval (https://yycrz.csb.app/node_modules/react-hook-form/dist/react-hook-form.js:886:28)"
To Reproduce https://codesandbox.io/s/react-hook-form-array-fields-validation-using-refs-yycrz?from-embed
Add two friends and then delete one friend. When you submit the form, you can see the error Chrome dev tools.
NOTE: if you do not provide a runnable reproduction the chances of getting feedback are significantly lower
Expected behavior A clear and concise description of what you expected to happen. Handle the scenario where r is undefined to fail gracefully so it does not break the running script.
Platform (please complete the following information):
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
Additional context
Add any other context about the problem here.
Also, one of the folks at React Hook Form asked me to share this screenshot:
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 8
- Comments: 19 (6 by maintainers)
@jquense So, this is the source of the bug: https://github.com/jquense/yup/blob/27b287ba0dd8981ddb330c28123b41d85c4c8853/src/util/runValidations.js#L38-L49
Here,
promises.map
is supposed to map fulfilled and rejected promises to the appropriate value object. However,Array.map
does not iterate over the empty spots in sparse arrays:It can probably be said that the error originates here: https://github.com/jquense/yup/blob/27b287ba0dd8981ddb330c28123b41d85c4c8853/src/array.js#L87
Here, no validation will be generated for empty Array positions.
It seems to me that for the purposes of this library, it makes sense to convert empty array positions to
undefined
in the output.I’m having the same issue, removing first element breaks validation. I’m using React Hook Form.
Adding check here https://github.com/jquense/yup/blob/0c27f076668632912311226259745d19129bf9bb/src/util/runValidations.js#L62
.filter(r => r ? !r.fulfilled : false)
fixes it for me locally. Hope it will be fixed.
@sdwvit there is a fix in #950.
In the mean time, what is most probably happening is that you have an array notation in a Field name, eg:
You can work around the problem by setting the initial values of that array manually to undefined:
More generally, every time you deal with a form field name that addresses an array position, make sure that the array position actually exists in the form’s
initialValues
by doingnew Array(5).fill(undefined)
.Otherwise, formik / react-hook-form create sparse arrays, and Yup before #950 breaks when trying to validate a sparse array.
happy to add better error handling but i don’t know where this error is being thrown or why.
I have same issue (also using React Hooks Form). In my case it happens when using additional sub inputs with checkboxes that reference to index of mapped out checkboxes. When I submit form and validation is triggered, it does not like that my array starts from 3 or 5 etc… when array 0 is undefined I get this: “Cannot read property ‘fulfilled’ of undefined”
Also the field validation is way off if you compact the array, then the error reference stops working with the form (so no help there).
Here is a code sandbox showing my issue, if you submit first checkbox it works, if you submit any of the other not having index in numerical order it fails: https://codesandbox.io/s/react-hook-form-checkbox-array-with-inputs-g6pd4?from-embed
In some rare circumstances, you could work around this by adding array.compact to your schema.
Keep in mind this will not actually omit the empty values from the output of formik/react-hook-form/etc.
However, it might be useful if you’re using yup directly, or in circumstances where you can combine it with something like
.min(x).max(x)
, wherex
is the same number for bothmin()
andmax()
.