fix: exclude React elements from deepmerge to prevent infinite recursion (fixes #4038) - #4080
Conversation
Validation error values may be arbitrary React nodes (rich error messages rendered in the UI). React elements are plain objects whose props can contain nested elements, so deepmerge recurses into them indefinitely and throws 'Maximum call stack size exceeded'. Add a custom isMergeableObject that marks React elements (and other non-plain objects like Date, RegExp, Promise) as non-mergeable so they pass through untouched. Fixes jaredpalmer#4038
|
@ErfanBagheri404 is attempting to deploy a commit to the Formik Team on Vercel. A member of the Team first needs to authorize it. |
|
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
Summary
Fixes #4038 —
ReactNodevalidation errors crash Formik withMaximum call stack size exceededfromdeepmerge.Root cause
Validation error objects (
fieldErrors,schemaErrors,validateErrors) are merged viadeepmerge.all()inFormik.tsx. When an error value is a React element (e.g. a rich error message like<span>required</span>), deepmerge recurses into it — React elements are plain objects whosepropscan contain nested elements — and recurses indefinitely until the stack overflows.Change
Pass a custom
isMergeableObjectto deepmerge that returnsfalsefor React elements (detected via$$typeof === Symbol.for('react.element')) and other non-plain objects (Date,RegExp,Promise). These values pass through untouched while normal plain-object error merging is unchanged.Verification
Reproduced locally with a standalone script using
formik's bundleddeepmerge: nested React elements as validation errors overflow the stack without the option and merge cleanly with it. The fix matches the approach suggested in the issue.node_modules/.bin/tsccould not run under this environment (no package-level tsconfig; tests use tsdx/babel), so the change was verified via isolated reproduction of the merge behavior rather than the full suite.