Skip to content

Fix 'Maximum update depth exceeded' on large TabbedForm submit#11291

Open
imrans110 wants to merge 2 commits into
marmelab:masterfrom
imrans110:fix/tabbedform-maximum-update-depth
Open

Fix 'Maximum update depth exceeded' on large TabbedForm submit#11291
imrans110 wants to merge 2 commits into
marmelab:masterfrom
imrans110:fix/tabbedform-maximum-update-depth

Conversation

@imrans110

@imrans110 imrans110 commented Jun 24, 2026

Copy link
Copy Markdown

Problem

Submitting a <TabbedForm> with many required fields throws "Maximum update depth exceeded" (React's NESTED_UPDATE_LIMIT). The same fields in a <SimpleForm> work fine. Reported in #11290 with a verified reproduction.

Root cause: useFormGroup subscribes to react-hook-form's validatingFields to compute a group-level isValidating that is not consumed anywhere (FormTabHeader and TranslatableInputsTab read only isValid). Because react-admin wraps every validator as async in useInput, react-hook-form toggles validatingFields per field on submit; subscribing to it re-renders every form group on each toggle, so a TabbedForm with enough required fields across tabs exceeds React's maximum update depth. SimpleForm has no FormGroup, so it is unaffected.

Solution

Stop subscribing to validatingFields in useFormGroup. The unused group-level isValidating becomes a constant false. Validation and the tab error badges — driven by errors / isValid — are unchanged. Per-input async validation spinners are unaffected, since those come from each input's own fieldState.isValidating (useController), not from useFormGroup.

How To Test

  • Open the new ManyRequiredInputs story (ra-ui-materialui/forms/TabbedForm) in Storybook and click SAVE with the fields empty: on master it throws "Maximum update depth exceeded"; with this fix it validates normally.
  • Run the regression unit test:
    yarn test-unit packages/ra-core/src/form/groups/useFormGroup.spec.tsx -t "validating state"
    It fails on master (the group re-renders ~38× on repeated re-validation) and passes with this fix.

The crash is timing-sensitive in a real browser; jsdom batches updates via act() and does not reproduce the depth overflow, so the unit test targets the underlying re-render behaviour while the Storybook story provides the in-browser check.

Additional Checks

  • The PR targets master for a bugfix or a documentation fix, or next for a feature
  • The PR includes unit tests (if not possible, describe why)
  • The PR includes one or several stories (if not possible, describe why)
  • The documentation is up to date (no change needed — the only isValidating reference in the docs uses react-hook-form's global useFormState().isValidating, which this change does not affect)

Closes #11290

useFormGroup subscribed to react-hook-form's validatingFields only to
compute a group-level isValidating that is not consumed anywhere (both
FormTabHeader and TranslatableInputsTab read isValid only). Because
react-admin wraps every validator as async, react-hook-form toggles
validatingFields per field on submit; subscribing to it re-renders every
form group on each toggle, so a TabbedForm with many required fields
exceeds React's maximum update depth.

Stop subscribing to validatingFields. Tab error badges and validation
(driven by errors/isValid) are unaffected.

Closes marmelab#11290
@fzaninotto

Copy link
Copy Markdown
Member

as seen in #11290, we need a reproduction first.

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.

TabbedForm with many required (async-wrapped) validators throws "Maximum update depth exceeded" on submit

2 participants