Skip to content

fix(form-core): clear stale onMount error on linked-field revalidation#2244

Open
xianjianlf2 wants to merge 1 commit into
TanStack:mainfrom
xianjianlf2:fix/clear-stale-onmount-linked-revalidation-2124
Open

fix(form-core): clear stale onMount error on linked-field revalidation#2244
xianjianlf2 wants to merge 1 commit into
TanStack:mainfrom
xianjianlf2:fix/clear-stale-onmount-linked-revalidation-2124

Conversation

@xianjianlf2

@xianjianlf2 xianjianlf2 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Problem

A field-level onMount error is cleared when the field's own value changes, but not when the field is revalidated indirectly through onChangeListenTo / onBlurListenTo. After a passing cross-field revalidation the stale mount-time error lingers, so the field (and the whole form) stays permanently invalid (#2124).

Root cause

FormApi.setFieldValue clears errorMap.onMount on a direct value change, treating onMount as a mount-time snapshot. Linked-field revalidation re-runs the field's validators without changing its value, so that clearing never runs.

Fix

Thread an isLinkedField flag into validateFieldFn; on a passing linked-field revalidation, clear the stale onMount error/source slots. This mirrors the existing value-change clear and the adjacent "clear stale submit error on successful revalidation" logic in the same function.

Testing

Added a regression test in packages/form-core/tests/FieldApi.spec.ts (red before, green after). Full form-core suite (504 tests) passes with no type errors. Changeset included.

Closes #2124

Summary by CodeRabbit

  • Bug Fixes

    • Fixed stale field errors that could remain after linked-field validation succeeds.
    • Fields now correctly clear outdated mount-time errors when related field changes trigger successful revalidation.
    • Form and field validity states now update correctly without requiring the affected field’s value to change.
  • Tests

    • Added coverage for linked-field revalidation and stale error removal.

A field-level `onMount` error was cleared when the field's own value
changed (via `setFieldValue`), but never when the field was revalidated
indirectly through `onChangeListenTo`/`onBlurListenTo`. Because a linked
revalidation does not change the field's value, the mount-time error
lingered even after the field's validators passed, leaving the field
(and the form) permanently invalid.

Clear the stale `onMount` slot when a passing linked-field revalidation
supersedes it, mirroring the existing value-change behavior.

Closes TanStack#2124
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Linked-field revalidation now clears stale field-level onMount errors when validation succeeds. A regression test verifies field and form validity restoration, and a patch changeset documents the fix.

Changes

Linked-field validation

Layer / File(s) Summary
Clear stale onMount errors during linked validation
packages/form-core/src/FieldApi.ts, packages/form-core/tests/FieldApi.spec.ts, .changeset/clear-stale-onmount-linked-revalidation.md
validateSync identifies linked-field validation calls and clears persisted onMount errors after successful revalidation. Tests verify the linked field and form become valid, and the changeset records a patch release.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: lecarbonator

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is detailed, but it does not follow the repository template sections for Changes, Checklist, and Release Impact. Rewrite the description using the required template headings and fill in the checklist and release-impact sections.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the linked-field onMount error fix.
Linked Issues check ✅ Passed The code and test changes address #2124 by clearing stale onMount errors on successful linked-field revalidation and restoring validity.
Out of Scope Changes check ✅ Passed The changes are in scope: code, regression test, and changeset all support the linked-field onMount error fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/form-core/tests/FieldApi.spec.ts (1)

2304-2353: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Good regression test; consider adding onBlurListenTo coverage.

The test correctly validates the core sync scenario. Since the PR objectives mention both onChangeListenTo and onBlurListenTo, adding a parallel test for blur-triggered revalidation would protect against regressions in the blur path.

🧪 Suggested additional test for onBlurListenTo
+  it('should clear a stale onMount error when a linked field blur revalidation passes', () => {
+    const form = new FormApi({
+      defaultValues: {
+        password: '',
+        confirm_password: 'password',
+      },
+    })
+
+    form.mount()
+
+    const passField = new FieldApi({ form, name: 'password' })
+    const passconfirmField = new FieldApi({
+      form,
+      name: 'confirm_password',
+      validators: {
+        onMount: ({ value, fieldApi }) =>
+          value !== fieldApi.form.getFieldValue('password')
+            ? 'Passwords do not match'
+            : undefined,
+        onBlurListenTo: ['password'],
+        onBlur: ({ value, fieldApi }) =>
+          value !== fieldApi.form.getFieldValue('password')
+            ? 'Passwords do not match'
+            : undefined,
+      },
+    })
+
+    passField.mount()
+    passconfirmField.mount()
+
+    expect(passconfirmField.state.meta.errorMap.onMount).toBe('Passwords do not match')
+    expect(passconfirmField.getMeta().isValid).toBe(false)
+
+    passField.setValue('password')
+    passField.handleBlur()
+
+    expect(passconfirmField.state.meta.errorMap.onMount).toBeUndefined()
+    expect(passconfirmField.state.meta.errors).toStrictEqual([])
+    expect(passconfirmField.getMeta().isValid).toBe(true)
+    expect(form.state.isValid).toBe(true)
+  })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/form-core/tests/FieldApi.spec.ts` around lines 2304 - 2353, Add a
parallel regression test alongside the existing linked-field test covering
onBlurListenTo: configure the dependent field with an onMount error and
blur-triggered validation, trigger revalidation by blurring the linked field
after correcting its value, and assert the stale onMount error is cleared and
both field and form validity become true.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/form-core/tests/FieldApi.spec.ts`:
- Around line 2304-2353: Add a parallel regression test alongside the existing
linked-field test covering onBlurListenTo: configure the dependent field with an
onMount error and blur-triggered validation, trigger revalidation by blurring
the linked field after correcting its value, and assert the stale onMount error
is cleared and both field and form validity become true.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3299dd8a-a492-4a08-8a92-22e99a987e12

📥 Commits

Reviewing files that changed from the base of the PR and between 5d11281 and 70e92d4.

📒 Files selected for processing (3)
  • .changeset/clear-stale-onmount-linked-revalidation.md
  • packages/form-core/src/FieldApi.ts
  • packages/form-core/tests/FieldApi.spec.ts

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.

Field-level onMount errors are never cleared on linked-field revalidation

1 participant