Describe the bug
FormApi's sync validation has the same bug that #2211 is fixing at the field level, just one level up. In packages/form-core/src/FormApi.ts, the block that's supposed to clear a stale onSubmit error "as soon as the user enters a valid value" checks cause !== 'submit' instead of cause === 'change':
const submitErrKey = getErrorMapKey('submit')
if (
this.state.errorMap?.[submitErrKey] &&
cause !== 'submit' &&
!hasErrored
) {
this.baseStore.setState((prev) => ({
...prev,
errorMap: { ...prev.errorMap, [submitErrKey]: undefined },
}))
}
ValidationCause is 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic', so this clears the submit error on blur, mount, server, and dynamic validation runs too, not just when the user actually changes a value. The comment right above it says the intent is "clear the error as soon as the user enters a valid value in the field", which only 'change' represents.
The exact same block exists again a few lines down for onServer errors, with the same shape (cause !== 'server'), so it has the analogous problem: a server-side error can get cleared by a blur or an unrelated dynamic revalidation instead of only by the user actually changing the value.
I think this is what #1472 was really running into. That issue was closed as a React Native Web quirk (RNW fires a blur event on submit, and blurOnSubmit={false} was suggested as the workaround), but the underlying reason blur clears the error at all is this condition, so the same symptom is reachable on plain web too, any blur on a field with an existing submit error clears it, RNW's extra blur-on-submit event just makes it show up immediately and consistently.
Your minimal, reproducible example
Not a runnable repro since this is internal form-core logic, but here's the sequence that reaches the bug directly through the public API:
const form = new FormApi({ defaultValues: { name: '' } })
form.mount()
const field = new FieldApi({
form,
name: 'name',
validators: { onSubmit: ({ value }) => (value.length > 0 ? undefined : 'required') },
})
field.mount()
await form.handleSubmit() // form.state.errorMap.onSubmit is now set
field.handleBlur() // no value change, just a blur
// form.state.errorMap.onSubmit is cleared here, even though nothing was fixed
Steps to reproduce
- Create a form with an
onSubmit validator on a field.
- Submit without satisfying the validator so
errorMap.onSubmit gets set.
- Blur the field (or trigger any
mount/server/dynamic validation) without changing its value.
form.state.errorMap.onSubmit is cleared, even though the underlying problem wasn't fixed.
Expected behavior
The submit-level error should only clear when the cause is 'change', matching the comment's stated intent and consistent with how #2211 is fixing the identical check at the field level.
Platform
n/a (form-core logic, framework-agnostic)
TanStack Form version
current main, packages/form-core/src/FormApi.ts
Describe the bug
FormApi's sync validation has the same bug that #2211 is fixing at the field level, just one level up. Inpackages/form-core/src/FormApi.ts, the block that's supposed to clear a staleonSubmiterror "as soon as the user enters a valid value" checkscause !== 'submit'instead ofcause === 'change':ValidationCauseis'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic', so this clears the submit error onblur,mount,server, anddynamicvalidation runs too, not just when the user actually changes a value. The comment right above it says the intent is "clear the error as soon as the user enters a valid value in the field", which only'change'represents.The exact same block exists again a few lines down for
onServererrors, with the same shape (cause !== 'server'), so it has the analogous problem: a server-side error can get cleared by a blur or an unrelated dynamic revalidation instead of only by the user actually changing the value.I think this is what #1472 was really running into. That issue was closed as a React Native Web quirk (RNW fires a
blurevent on submit, andblurOnSubmit={false}was suggested as the workaround), but the underlying reason blur clears the error at all is this condition, so the same symptom is reachable on plain web too, any blur on a field with an existing submit error clears it, RNW's extra blur-on-submit event just makes it show up immediately and consistently.Your minimal, reproducible example
Not a runnable repro since this is internal form-core logic, but here's the sequence that reaches the bug directly through the public API:
Steps to reproduce
onSubmitvalidator on a field.errorMap.onSubmitgets set.mount/server/dynamicvalidation) without changing its value.form.state.errorMap.onSubmitis cleared, even though the underlying problem wasn't fixed.Expected behavior
The submit-level error should only clear when the cause is
'change', matching the comment's stated intent and consistent with how #2211 is fixing the identical check at the field level.Platform
n/a (form-core logic, framework-agnostic)
TanStack Form version
current main,
packages/form-core/src/FormApi.ts