zod-form-adapter turns all errors into one comma separated string, meta.errors assumes an array
Describe the bug
At the moment the zod-form-adapter's zodValidator validate and validateAsync functions turn the errors that zod reports into a comma separated string:
return result.error.issues.map((issue) => issue.message).join(', ')
When we want to display the Error(s) to the User the field.state.meta.errors field returns an array ValidationError[] which now only has one entry (the comma separated string.
Your minimal, reproducible example
https://stackblitz.com/edit/tanstack-form-r8vroz?file=src%2Findex.tsx
Steps to reproduce
- Open the Stackblitz
- The Form is already in the Error state (the Input
#does not match the min-length nor the regex (letters a-Z) - Observe: both Error messages are separated by a comma and a space => should only be a comma, see FieldInfo-Function
- You can also check the Console (you can filter for the string "errors")
Expected behavior
As a User
I expect field.state.meta.errors to be an array (type: ValidationError[]) with a length that matches the number of errors that resulted from the zod schema validation
BUT
I'm seeing an array (type: ValidationError[]) with the length of 1 no matter how many validation errors occurred.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
Not platform related
TanStack Form adapter
react-form
TanStack Form version
0.32.0
TypeScript version
No response
Additional context
No response
I think there is a bug in the definition of the ValidationError type
It is currently defined as:
export type ValidationError = undefined | false | null | string
Searching through the codebase there are places where ValidationError | undefined is specified:
const validatesPromises: Promise<ValidationError | undefined>[] = []
const linkedPromises: Promise<ValidationError | undefined>[] = []
This doesn't make sense as ValidationError already includes undefined in the union type.
Then there's this:
/**
* An array of errors related to the field value.
*/
errors: ValidationError[]
where errors is an array of ValidationError - where the items of the array could be of type undefined | false | null | string so working with the errors requires an additional falsy check.
How to fix it?
My guess is that the ValidationError should be Array<string> | undefined | false | null
Related Issues
- This discussion seams related as well: https://github.com/TanStack/form/discussions/946
I have the same issue and wonder why this issue is not commented/flagged yet. Is this a bug or a feature? Personally, I would prefer not having the errors be joined and would therefore export an array with the custom transformErrors option.
I have the same issue too.
@adhithiya05 You can work around this by using the transformErrors option of the zodValidator like so; sadly it doesn't allow returning an array currently:
validatorAdapter: zodValidator({
transformErrors: (errors) => {
return errors.map(error => error.message).join('#!#');
}
}),
And somewhere in your form / component you simply split the error again:
errors[0].split('#!#');
The meta.errors array contains the errors from all validators, that's why if you only have the onChange set you'll either find an empty array or an array with one element. It is working as expected and there's no bug to fix there.
Allowing to return an array of errors from a single validator might be a completely different topic, I wrote down some notes in the discussion at #946