Skip to content

Form-level validator doesn't re-run after first submit while fields hold errors — bug or by design? #2248

Description

@micxu-CITCO

Describe the bug

With a form-level onSubmit validator only (no field-level validators) and the default validation logic:

The first submit runs the validator and populates all field errors.
After that, canSubmit is false (since submissionAttempts > 0 and isValid === false), so every subsequent submit hits the guard at the top of _handleSubmit and returns early — no further validation runs until the user has cleared all outstanding errors.
That part I understand is likely intended (button-disable pattern). My real question is about the next layer:

The specific question
When I set canSubmitWhenInvalid: true to allow re-submitting while invalid, the form-level validator still doesn't re-run. Tracing _handleSubmit:

await this.validateAllFields("submit");     // field-level only; no-op when I have no field validators
if (!this.state.isFieldsValid) return;       // <-- bails here because stale field errors remain
await this.validate("submit");               // <-- form-level schema; never reached

Because we only have a form-level validator, validateAllFields can't clear or recompute anything, so isFieldsValid stays false from the previous submit, and validate("submit") (the call that re-runs the form schema) is skipped.

Is this intended? Specifically: should validateAllFields returning stale field errors prevent the form-level validator from re-running on submit? It means a form configured with only a form-level validator can never re-validate on a second submit while any error is outstanding.

Your minimal, reproducible example

see below

Steps to reproduce

const form = useForm({
  defaultValues: { name: '', other: '' },
  validators: {
    onSubmit: ({ value }) => {
      const errors = {};
      if (!value.name) errors.name = 'Required';
      if (!value.other) errors.other = 'Required';
      return Object.keys(errors).length ? { fields: errors } : undefined;
    },
  },
  canSubmitWhenInvalid: true,
});
  1. submit empty -> both fields error
  2. type into name, clear it (error clears on change)
  3. submit again -> name error does NOT return; other still errors

Expected behavior

On each submit, the form-level validator re-runs and reflects the current values (so name would error again in step 3).

How often does this bug happen?

None

Screenshots or Videos

No response

Platform

macOS, chrome

TanStack Form adapter

None

TanStack Form version

v1.29.1

TypeScript version

v^6.0.3

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions