form icon indicating copy to clipboard operation
form copied to clipboard

Field validation errors returned by the `onMount` validator never make it to the Field instance

Open dlindahl opened this issue 9 months ago • 1 comments

Describe the bug

A field's meta object is never assigned the field validation errors returned by the onMount validator.

Through some local line-by-line debugging this is how I interpret the internals of the FormApi and the root cause of the issue:

  1. The FormApi constructor defines this.mount to be a function called when the instance is mounted.
  2. The mount function internally calls validateSync with a cause value of "mount" if there is an onMount validator defined.
  3. validateSync then calls batch which parses the return value of the onMount validator.
  4. Once it has built an internal map of field errors and form errors, it then attempts to assign each field error to the appropriate field by calling this.setFieldMeta with the name of the field that has errors. So assuming that onMount returns the object: { fields: { myField: "my error", myOtherField: "my other error" } }, it will iterate over the keys of fields and attempt to set the error "my error" to the myField field instance meta and "my other error" to the myOtherField field instance meta.
  5. However, in my debugging, this.getFieldMeta(field), does not return anything because, I assume, the fields do not yet exist so the check for fieldMeta && fieldMeta.errorMap[errorMapKey] will never return true and thus the validation error is never set on the field. this.state.fieldMeta is an empty object at this point of the FormApi's lifecycle.

Further debugging proves that the FormApi's field meta object is not defined until, as far as I can tell, ~the store is accessed for the first time.~ the FieldApi instance is mounted for the first time which seems to occur after the FormApi is considered mounted which means this would never work? 🤷

Your minimal, reproducible example

https://stackblitz.com/edit/vitejs-vite-sqnkac55?file=src%2FApp.tsx,package.json

Steps to reproduce

This minimal reproducible example is a fork from the example noted in #1149 where the only thing I changed was the version number from 0.43.0 to the latest 1.2.3

  1. Go to https://stackblitz.com/edit/vitejs-vite-sqnkac55?file=src%2FApp.tsx,package.json
  2. Note that the bottom of the page shows the field states and they are all valid.
  3. Now go to the original example from #1149 https://stackblitz.com/edit/vitejs-vite-ronky49r?file=src%2FApp.tsx
  4. Note that the field states are now all invalid due to the functional onMount validator.

Expected behavior

As a user, I expect field errors reported by the onMount validator to be a part of the FieldApi meta and the field to be considered invalid.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

OS: macOs Browser: Chrome Version: 134.0.6998.89 (Official Build) (arm64)

TanStack Form adapter

react-form

TanStack Form version

v1.2.3

TypeScript version

No response

Additional context

This appears to be a regression between 0.43 and 1.2.3.

dlindahl avatar Apr 01 '25 19:04 dlindahl

Thanks for the investigation, your analysis looks solid!

Do you want to give it a try with a PR?

Balastrong avatar Apr 02 '25 18:04 Balastrong