Field async validation reapplies stale errors after form.reset()
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.7k
- Forks
- 682
- Avg merge
- 5d 18h
- Merged PRs (30d)
- 7
Description
Describe the bug
If a field's onChangeAsync validation is already running when form.reset() is called, its result can reapply an error for the previous input after the field value and errors have been reset.
For example, a user edits an email field and then clicks Reset while a remote check is pending. The input returns to its initial value, but the previous input's error appears when the check finishes, without another edit or validation request.
Your minimal, reproducible example
Deterministic regression test on unmodified production code
This commit adds tests only to upstream 57a855b42b9b99cee5ca12890b70c7df84e2982c. It uses a deferred promise and fake timers, with no server dependency.
git clone https://github.com/lunaxislu/form.git
cd form
git checkout 73f777c611db50f97c4df37f112b0bdecadad407
# Use Node 24.8.0 from .nvmrc and the packageManager version via Corepack.
corepack pnpm install --frozen-lockfile
corepack pnpm --dir packages/form-core exec vitest run tests/FieldApi.spec.ts -t 'should not reapply a stale onChangeAsync error'
Steps to reproduce
- Mount a form and an email field with a deferred
onChangeAsyncvalidator. - Set the field to
not-an-emailand let the validator start. - Call
form.reset()before resolving the validator. The value is restored to''and the field errors are empty. - Resolve the pending validator with
not-an-email is not valid. - Observe that
field.state.meta.errorMap.onChangecontains that error again, although the value is still''.
setValue('not-an-email') -> validation A starts
reset() -> value='', errors=[]
validation A finishes -> value='', errors=['not-an-email is not valid']
Expected behavior
The result for the pre-reset input should not repopulate the errors cleared by reset. This does not assume that the initial value is valid or request that reset run validation again.
The test passes its assertions immediately after reset, then fails after the old result settles:
Expected: undefined
Received: "not-an-email is not valid"
A control test without reset confirms that completed validation still applies its error normally.
How often does this bug happen?
Every time with the controlled ordering above.
Platform
macOS; reproduced in the form-core Vitest suite (jsdom). No browser-specific behavior is required.
TanStack Form adapter
vanilla (@tanstack/form-core)
TanStack Form version
1.33.5, source at 57a855b42b9b99cee5ca12890b70c7df84e2982c on main.
TypeScript version
5.9.3
Additional context
FormApi.reset() resets field metadata but does not abort the controllers in each field's validationMetaMap. The field async result checks for an aborted signal or a replaced field instance; neither happens on reset.
This report concerns stale field-level errors after a full form reset. Related PRs #2047 and #2373 concern validation status/accounting; #2247 concerns shifted array metadata. I did not find the same reset/error scenario in the issue, PR, and Discussion searches I checked.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/form-core/tests/FieldApi.spec.ts and run the provided Vitest test for “should not reapply a stale onChangeAsync error.” Read FormApi.reset() and the field validationMetaMap behavior described in the issue; done means the pre-reset async result no longer restores cleared errors while the control case still applies validation errors normally.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100