You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[next.js] initialFormState and no fields rendered may cause state.values undefined #1923
I expect values to always be defined, as should all of the fields in my schema.
The bug is in application code! ...but following the docs' recommendations 🤔, and using initialFormState which introduces the issue.
How often does this bug happen?
Often
Screenshots or Videos
No response
Platform
Fedora
Firefox / Zen
TanStack Form adapter
None
TanStack Form version
v1.27.1
TypeScript version
v5.9.3
Additional context
I'm not sure if this is a docs issue instead of any type of bug, i'll leave it up to you!
I'd say the bottom line is not sure why the values should be allowed to be undefined, and thus if either initialFormState should be something that adapts to the form schema, or outright don't recommend it and make the user write it manually, maybe copying the default values (which is more or less the fix i implemented).
Is the recommendation now to use the specific package @tanstack/react-form-nextjs for everything? I see it re-exports everything from @tanstack/react-form
If there's a <form.Field> for a field, any field of the form, then it somehow ammends the values (even if it doesn't render anything itself).
In my case i have an <Activity mode={isSubmitSuccessful ? "visible" : "hidden"> wrapping the only field, which means no fields are being rendered on the first pass. If i either add another <form.AppField> that always renders or if i hide the field with CSS instead, then no error is thrown.
I'll upload a repro, clearly it was the correct path.
changed the title [-][next.js] `initialFormState` breaks Subscribe components if merging as in SSR guide[/-][+][next.js] `initialFormState` and no fields rendered may cause `state.values` undefined[/+]on Dec 8, 2025
So leaving that investigation here, hope it's useful, luckily it's clear that i can workaround this issue by always having some field rendered since the first pass.
I am now having this problem more often, maybe because i've turned on Next.js' cacheComponents (https://nextjs.org/docs/app/getting-started/cache-components) and now many more things are wrapped in <Activity>. Has any solution cropped up since i posted this? Weird that no one else is bumping against this. I've already updated to the latest Tanstack Form versions.
In the meantime, Opus came up with using an alternative initialFormState as a workaround:
/** * Drop-in replacement for `initialFormState` from `@tanstack/react-form-nextjs`. * The upstream version includes `values: undefined`, which causes `mergeForm` / * `mutateMergeDeep` to overwrite the real form values with `undefined`. * This is especially problematic when Next.js wraps routes in `<Activity>` (cache * components / PPR), since no `<Field>` may be mounted on the first render pass. * See: https://github.com/TanStack/form/issues/1923 */exportconstinitialFormState={errorMap: {onServer: undefined},errors: [],// IMPORTANT: values must be `{}` not `undefined`. The upstream `initialFormState`// uses `undefined`, which causes `mutateMergeDeep` to overwrite the real form// values with `undefined` — crashing any `Subscribe` selector that reads `state.values`.values: {},// eslint-disable-next-line @typescript-eslint/no-explicit-any}asServerFormState<any,undefined>
Not sure its logic is completely correct but it does solve the runtime issue for me and i guess the final type assert makes everything behave as before. Of course if we can come up with a sane fix instead of this i'll update :)
Activity
MartinCura commentedon Dec 8, 2025
Wait i've done a minimal repro and i can't reproduce 🤔 investigating...
MartinCura commentedon Dec 8, 2025
Is the recommendation now to use the specific package
@tanstack/react-form-nextjsfor everything? I see it re-exports everything from@tanstack/react-formMartinCura commentedon Dec 8, 2025
Ok i think i'm pinning it down:
If there's a
<form.Field>for a field, any field of the form, then it somehow ammends thevalues(even if it doesn't render anything itself).In my case i have an
<Activity mode={isSubmitSuccessful ? "visible" : "hidden">wrapping the only field, which means no fields are being rendered on the first pass. If i either add another<form.AppField>that always renders or if i hide the field with CSS instead, then no error is thrown.I'll upload a repro, clearly it was the correct path.
MartinCura commentedon Dec 8, 2025
https://github.com/MartinCura/tanstack-form-1923
just look at the
client-component.tsxthe first commit is a copy of the base example, except for package upgrades that leaked in there
[-][next.js] `initialFormState` breaks Subscribe components if merging as in SSR guide[/-][+][next.js] `initialFormState` and no fields rendered may cause `state.values` undefined[/+]MartinCura commentedon Dec 8, 2025
So leaving that investigation here, hope it's useful, luckily it's clear that i can workaround this issue by always having some field rendered since the first pass.
crutchcorn commentedon Dec 8, 2025
I suspect this work on my end may fix issues here:
#1890
But I could be wrong. Will validate later
MartinCura commentedon Dec 9, 2025
Interesting, thank you for the quick answer!
It may be of interest that console.log'ing i see
valuesdefinedvaluesfirst defined then undefinedNo hurry here, and do tell me if i can give a hand in debugging.
MartinCura commentedon Mar 2, 2026
Goddammit i put Claude to investigate a strange bug and it linked it... to my own GitHub issue 😅
MartinCura commentedon Mar 2, 2026
I am now having this problem more often, maybe because i've turned on Next.js'
cacheComponents(https://nextjs.org/docs/app/getting-started/cache-components) and now many more things are wrapped in<Activity>. Has any solution cropped up since i posted this? Weird that no one else is bumping against this. I've already updated to the latest Tanstack Form versions.MartinCura commentedon Mar 2, 2026
In the meantime, Opus came up with using an alternative
initialFormStateas a workaround:Not sure its logic is completely correct but it does solve the runtime issue for me and i guess the final type assert makes everything behave as before. Of course if we can come up with a sane fix instead of this i'll update :)