Skip to content

fix(form-core): fix stale async validators from updating isValidating to false#2047

Open
AdrianLea wants to merge 3 commits intoTanStack:mainfrom
AdrianLea:main
Open

fix(form-core): fix stale async validators from updating isValidating to false#2047
AdrianLea wants to merge 3 commits intoTanStack:mainfrom
AdrianLea:main

Conversation

@AdrianLea
Copy link

@AdrianLea AdrianLea commented Feb 18, 2026

fixes #2045

🎯 Changes

Two bugs fixed in validateAsync within FieldApi.ts:

1. Abort controller stored on the wrong field

validateFieldAsyncFn is called for both the main field and linked fields, but always wrote the new AbortController to this.getInfo() instead of field.getInfo(). This was a copy-paste oversight — the read side already used field.getInfo() correctly, but the write side was never updated when linked field support was added. This meant:

  • Linked fields never recorded their own controller
  • When the main field failed sync validation and tried to abort linked fields via linkedField.getInfo().validationMetaMap[errorMapKey]?.lastAbortController.abort(), the entry was always undefined — linked fields' async validators were silently never cancelled

2. No supersession check — isValidating unconditionally cleared

After all async promises resolved, the original code was:

if (hasAsyncValidators) {
  this.setMeta((prev) => ({ ...prev, isValidating: false }))
  for (const linkedField of linkedFields) {
    linkedField.setMeta((prev) => ({ ...prev, isValidating: false }))
  }
}

This unconditionally cleared isValidating on every field regardless of whether a newer async validation run had started in the meantime, causing a stale run to clobber the isValidating state of an in-progress one.

Fix:

  • Write the controller to field.getInfo() instead of this.getInfo()
  • Create a mapping of AbortSignal to (field, errorMapKey) and check if the current AbortSignal is still the latest for that specific field and key before clearing isValidating, so a stale run completing can't prematurely reset a newer run's validating state

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

@changeset-bot
Copy link

changeset-bot bot commented Feb 18, 2026

⚠️ No Changeset found

Latest commit: 4e0cb45

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@AdrianLea AdrianLea marked this pull request as draft February 18, 2026 15:50
@AdrianLea AdrianLea marked this pull request as ready for review February 18, 2026 15:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isValidating state updates to false before debounced async validation completes

1 participant

Comments