Skip to content

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

Open
mixelburg wants to merge 1 commit intoTanStack:mainfrom
mixelburg:fix/onmount-linked-field-revalidation
Open

fix(form-core): clear stale onMount error on linked-field revalidation#2136
mixelburg wants to merge 1 commit intoTanStack:mainfrom
mixelburg:fix/onmount-linked-field-revalidation

Conversation

@mixelburg
Copy link
Copy Markdown

@mixelburg mixelburg commented Apr 21, 2026

Fixes #2124

When a field has an validator and is linked to another field via /, the onMount error was never cleared even when the linked-field validator confirmed the field was valid. This left and stuck.

The fix: after a sync or async validator runs on a field (or its linked field) and reports no error, if an entry is present, clear it — the later validation supersedes the mount-time check. Same pattern already used for clearing submit errors on change.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced form field validation to properly manage error states during synchronous and asynchronous validation cycles, ensuring outdated errors are cleared when fields become valid.
    • Improved error cleanup logic to prevent stale validation messages from one validation run from persisting into subsequent validation attempts, resulting in more accurate field status displays.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

📝 Walkthrough

Walkthrough

FieldApi's validation logic updated to conditionally clear stale onMount errors when other validators (onChange, onBlur) run successfully via linked-field revalidation. The fix constructs nextErrorMap before setMeta and includes logic to reset onMount errors when a non-onMount validator reports validity.

Changes

Cohort / File(s) Summary
FieldApi Validation Logic
packages/form-core/src/FieldApi.ts
Updated validateSync and validateAsync to construct nextErrorMap before calling setMeta. Added conditional logic to clear stale onMount errors when a non-onMount validator runs successfully (falsy newErrorValue) and a prior onMount error exists, enabling cross-field revalidation to properly reset mount-time errors.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A hop, skip, and jump through the validation flow,
Old mount-time errors now learn to let go,
When linked fields revalidate and all's well,
No stale ghosts linger—the onMount spell's quelled!
Fields bloom green with validity true,

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: clearing stale onMount errors during linked-field revalidation, which directly matches the primary change in the PR.
Description check ✅ Passed The PR description explains the bug, solution, and implementation pattern clearly. The associated checklist template items are understood in context, though not explicitly marked.
Linked Issues check ✅ Passed The code changes directly address issue #2124 by implementing the expected behavior: clearing stale onMount errors after linked-field validators confirm the field is valid.
Out of Scope Changes check ✅ Passed All changes are focused on the FieldApi validation logic to fix the onMount error-clearing bug; no unrelated or out-of-scope modifications are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/form-core/src/FieldApi.ts (1)

1947-1969: ⚠️ Potential issue | 🟡 Minor

Clear errorSourceMap.onMount to maintain consistency with errorMap.onMount.

The same issue exists here as in validateSync: when clearing errorMap.onMount, the corresponding errorSourceMap.onMount entry should also be cleared. This mirrors the submit error clearing pattern (lines 1787-1797).

Additionally, use optional chaining (prev.errorMap?.onMount) at line 1957 for defensive consistency with line 1950.

🔧 Proposed fix to clear errorSourceMap.onMount
           field.setMeta((prev) => {
             const nextErrorMap = {
               // eslint-disable-next-line `@typescript-eslint/no-unnecessary-condition`
               ...prev?.errorMap,
               [errorMapKey]: newErrorValue,
             }
+            const nextErrorSourceMap = {
+              ...prev.errorSourceMap,
+              [errorMapKey]: newSource,
+            }
             // Clear stale onMount error when a later validator confirms the field is valid
             if (
               !newErrorValue &&
               errorMapKey !== 'onMount' &&
-              prev.errorMap.onMount
+              prev.errorMap?.onMount
             ) {
               nextErrorMap.onMount = undefined
+              nextErrorSourceMap.onMount = undefined
             }
             return {
               ...prev,
               errorMap: nextErrorMap,
-              errorSourceMap: {
-                ...prev.errorSourceMap,
-                [errorMapKey]: newSource,
-              },
+              errorSourceMap: nextErrorSourceMap,
             }
           })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/form-core/src/FieldApi.ts` around lines 1947 - 1969, In
field.setMeta callback (the block updating errorMap/errorSourceMap), when you
clear errorMap.onMount you must also clear errorSourceMap.onMount to keep maps
consistent: update the logic that checks "!newErrorValue && errorMapKey !==
'onMount' && prev.errorMap.onMount" to use optional chaining
(prev.errorMap?.onMount) and, in that branch, set nextErrorSourceMap.onMount =
undefined (or remove it) alongside setting nextErrorMap.onMount = undefined;
reference the existing symbols errorMapKey, newErrorValue, newSource, prev,
errorMap, and errorSourceMap to locate and update this behavior inside the
field.setMeta callback.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/form-core/src/FieldApi.ts`:
- Around line 1738-1759: In field.setMeta's updater (the block handling
nextErrorMap), when you detect clearing a stale onMount error (the if that
checks !newErrorValue && errorMapKey !== 'onMount' && prev.errorMap.onMount),
also clear the corresponding entry in errorSourceMap (set
nextErrorSourceMap.onMount = undefined or ensure the returned errorSourceMap has
onMount removed) so errorMap and errorSourceMap stay in sync; additionally
change the check to use optional chaining (prev.errorMap?.onMount) for defensive
access. Reference: the field.setMeta updater, variables errorMapKey,
newErrorValue, newSource, and errorSourceMap in this diff.

---

Outside diff comments:
In `@packages/form-core/src/FieldApi.ts`:
- Around line 1947-1969: In field.setMeta callback (the block updating
errorMap/errorSourceMap), when you clear errorMap.onMount you must also clear
errorSourceMap.onMount to keep maps consistent: update the logic that checks
"!newErrorValue && errorMapKey !== 'onMount' && prev.errorMap.onMount" to use
optional chaining (prev.errorMap?.onMount) and, in that branch, set
nextErrorSourceMap.onMount = undefined (or remove it) alongside setting
nextErrorMap.onMount = undefined; reference the existing symbols errorMapKey,
newErrorValue, newSource, prev, errorMap, and errorSourceMap to locate and
update this behavior inside the field.setMeta callback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5da07b51-1570-4519-a1ac-93bc4e531c01

📥 Commits

Reviewing files that changed from the base of the PR and between 1cdd97a and 5489231.

📒 Files selected for processing (1)
  • packages/form-core/src/FieldApi.ts

Comment on lines +1738 to +1759
field.setMeta((prev) => {
const nextErrorMap = {
...prev.errorMap,
[errorMapKey]: newErrorValue,
},
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource,
},
}))
}
// Clear stale onMount error when a later validator confirms the field is valid
if (
!newErrorValue &&
errorMapKey !== 'onMount' &&
prev.errorMap.onMount
) {
nextErrorMap.onMount = undefined
}
return {
...prev,
errorMap: nextErrorMap,
errorSourceMap: {
...prev.errorSourceMap,
[errorMapKey]: newSource,
},
}
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clear errorSourceMap.onMount to maintain consistency with errorMap.onMount.

When clearing errorMap.onMount, the corresponding errorSourceMap.onMount entry should also be cleared to keep the two maps in sync. The existing submit error clearing logic (lines 1787-1797) clears both maps, establishing this pattern.

Additionally, use optional chaining (prev.errorMap?.onMount) at line 1747 for defensive consistency with line 1737.

🔧 Proposed fix to clear errorSourceMap.onMount
         field.setMeta((prev) => {
           const nextErrorMap = {
             ...prev.errorMap,
             [errorMapKey]: newErrorValue,
           }
+          const nextErrorSourceMap = {
+            ...prev.errorSourceMap,
+            [errorMapKey]: newSource,
+          }
           // Clear stale onMount error when a later validator confirms the field is valid
           if (
             !newErrorValue &&
             errorMapKey !== 'onMount' &&
-            prev.errorMap.onMount
+            prev.errorMap?.onMount
           ) {
             nextErrorMap.onMount = undefined
+            nextErrorSourceMap.onMount = undefined
           }
           return {
             ...prev,
             errorMap: nextErrorMap,
-            errorSourceMap: {
-              ...prev.errorSourceMap,
-              [errorMapKey]: newSource,
-            },
+            errorSourceMap: nextErrorSourceMap,
           }
         })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/form-core/src/FieldApi.ts` around lines 1738 - 1759, In
field.setMeta's updater (the block handling nextErrorMap), when you detect
clearing a stale onMount error (the if that checks !newErrorValue && errorMapKey
!== 'onMount' && prev.errorMap.onMount), also clear the corresponding entry in
errorSourceMap (set nextErrorSourceMap.onMount = undefined or ensure the
returned errorSourceMap has onMount removed) so errorMap and errorSourceMap stay
in sync; additionally change the check to use optional chaining
(prev.errorMap?.onMount) for defensive access. Reference: the field.setMeta
updater, variables errorMapKey, newErrorValue, newSource, and errorSourceMap in
this diff.

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