_handleSubmit gates form-level validation behind field-level validity, causing incomplete error reports on submit

Offen
#2,130 2 Kommentare 3 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

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

v1 v2: needs investigation
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
  1. Enter a value for field a, leave field b empty
  2. submit → Field b shows an error since it's empty
  3. clear field a
  4. submit again (notice canSubmitWhenInvalid is 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 canSubmitWhenInvalid is false (the default), existing field errors already prevent _handleSubmit from 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 into canSubmitWhenInvalid: 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

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus TanStack/form

Alle Issues in TanStack/form

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.