_handleSubmit gates form-level validation behind field-level validity, causing incomplete error reports on submit
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 55/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- react, typescript
- Bereich
- frontend
Rechercherichtung
Beginne bei _handleSubmit im React Form adapter und reproduziere das Verhalten mit der verknüpften CodeSandbox. Verfolge validateAllFields('submit'), das isFieldsValid-Gate und validate('submit'); abgeschlossen ist die Aufgabe, wenn die Submit-Validierung Fehler aus beiden Phasen meldet und der Pfad für ungültige Submits das kombinierte Ergebnis erhält.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Describe the bug
I believe this is a bug, though I want to flag upfront that the staging in _handleSubmit seems to be intentional. Regardless I'd like to argue the current behavior still isn't right.
_handleSubmit runs validation in two stages with an early return between them:
await this.validateAllFields('submit') // Stage 1: field-level validators
if (!this.state.isFieldsValid){ /* ... */ return } // Gate
await this.validate('submit') // Stage 2: form-level validators
If Stage 1 fails, users only see the errors from this stage. So any other invalid fields stay silent until these errors are fixed. This contradicts what users intuitively expect from a submit action: check everything and show all errors.
Setting canSubmitWhenInvalid: true also doesn't fix this. The flag gates whether _handleSubmit runs at all, not how validation is staged within it.
My use case:
I only use form-level validation and canSubmitWhenInvalid: true.
Form-level validators write their errors into individual fields' errorMap. But isFieldsValid reads those entries without distinguishing source. So after a failed submit, those form-level errors count as "field-level invalid" on the next attempt — the isFieldsValid gate triggers, form-level validation is skipped, and stale errors stay on screen while new ones never appear.
This mechanism appears to be the underlying cause / relevant for several issues that have been reported separately: #1874, #1663 (see TeChn4K's reproduction there), #2034
PR #2120 in response to #2034 addresses a narrower symptom and doesn't solve the core issue: In #2034 the user has an onBlur validation on a field with conditional validation logic based on another field. The reported issue can be fixed by linking the other field with onBlurListenTo or using canSubmitWhenInvalid: true. The PR does not touch the isFieldsValid gate, so it does not address the problems above.
Your minimal, reproducible example
https://codesandbox.io/p/sandbox/tanstack-form-bug-7yxscz
Steps to reproduce
- Enter a value for field a, leave field b empty
- submit → Field b shows an error since it's empty
- clear field a
- submit again (notice
canSubmitWhenInvalidis set to true) → only field b shows an error even though field a is also empty
Expected behavior
On submit, both stages should run unconditionally and isValid should be evaluated once over the combined result:
await this.validateAllFields('submit')
await this.validate('submit')
if (!this.state.isValid) {
// onSubmitInvalid with the full error picture
return
}
// onSubmit
Why I think this is the right behavior:
- It matches user intuition for submit. Submit is the moment users most need a complete error report. Partial reports force them to fix-submit-fix-submit until they've discovered every problem, which is worse UX than showing everything at once.
- When
canSubmitWhenInvalidisfalse(the default), existing field errors already prevent_handleSubmitfrom running, so this change should have no effect unless there are filed level validators in which case all errors would now surface on submit instead of only the field-level ones, which I'd argue is also the right behavior. It changes behavior for forms that explicitly opt intocanSubmitWhenInvalid: true— where a complete error report on every submit is exactly what you'd expect.
Happy to open a PR if there's a decision on this.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
not relevant
TanStack Form adapter
react-form
TanStack Form version
1.28.0
TypeScript version
No response
Additional context
No response
- Vorherrschende Sprache
- TypeScript
- Sterne
- 6.8k
- Forks
- 705
- Ø Merge
- 1 T. 12 Std.
- Gemergte PRs (30 T.)
- 14
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus TanStack/form
-
`isDefaultValue` is wrong when a field-level `defaultValue` is `null`Evtl. vergeben @fenet-as hat das vor 22 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
TanStack/form#2427 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Async validator doesn't re-trigger `isValidating` after first failed validationEvtl. vergeben @drewsephski hat das vor 26 Tagen übernommen. Offen
Schwierigkeit 2/5 1-2 Tage Anfängerfreundlichkeit 72/100
Maintainer antworten meist innerhalb von 1 Tag
-
[v2 alpha] devtools are always light modeEvtl. vergeben @dikshit-n hat das vor 60 Tagen übernommen. Offenarea: runtime scope: devtools type: bug v2
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
Maintainer antworten meist innerhalb von 1 Tag
-
FormGroupApi.getRelatedFields and FieldApi.validate() use unguarded startsWith for group membership, matching unrelated fields with a shared name prefixEvtl. vergeben @HDPark95 hat das vor 79 Tagen übernommen. Offenarea: runtime scope: core type: bug v1
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
TanStack/form#2337 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
FormApi: onSubmit/onServer error cleared on any non-matching validation cause, not just 'change'Evtl. wieder frei Ein Pull Request dazu wurde ohne Merge geschlossen. Offenv1 v2: needs investigation
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
Maintainer antworten meist innerhalb von 1 Tag
Ähnliche Issues
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 85/100
formbricks/formbricks#9918 ·
Maintainer antworten meist innerhalb von 1 Tag
-
enhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
thecodacus/pithagoras#364 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 72/100
openclimatefix/quartz-frontend#823 ·
Maintainer antworten meist innerhalb von 4 Tagen
-
area:agent-manager community needs-triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
Maintainer antworten meist innerhalb von 1 Tag
-
`contacts.create` posts to `/audiences/undefined/contacts` when `audienceId` is undefinedEvtl. vergeben @RaphaelFakhri hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
resend/resend-node#1176 ·
Maintainer antworten meist innerhalb von 1 Tag