Skip to content

[Flight] Fix dev-only crash when passing elements into 3rd party renderers#35690

Draft
eps1lon wants to merge 1 commit intofacebook:mainfrom
eps1lon:sebbie/02-04-_flight_fix_dev-only_crash_when_nesting_3rd_party_components
Draft

[Flight] Fix dev-only crash when passing elements into 3rd party renderers#35690
eps1lon wants to merge 1 commit intofacebook:mainfrom
eps1lon:sebbie/02-04-_flight_fix_dev-only_crash_when_nesting_3rd_party_components

Conversation

@eps1lon
Copy link
Collaborator

@eps1lon eps1lon commented Feb 4, 2026

Ran into a crash in Next.js in addAsyncInfo with Cannot redefine property: _debugInfo.

Fix is purely motivated by the types. Need to understand crash conditions and if the defect isn't somewhere higher up.

@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Feb 4, 2026
@react-sizebot
Copy link

Comparing: f84ce5a...d68d7c4

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB +0.05% 1.88 kB 1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 610.35 kB 610.35 kB = 107.89 kB 107.89 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB +0.11% 1.88 kB 1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 676.28 kB 676.28 kB = 118.85 kB 118.85 kB
facebook-www/ReactDOM-prod.classic.js = 695.91 kB 695.91 kB = 122.28 kB 122.28 kB
facebook-www/ReactDOM-prod.modern.js = 686.29 kB 686.29 kB = 120.68 kB 120.68 kB

Significant size changes

Includes any change greater than 0.2%:

(No significant changes)

Generated by 🚫 dangerJS against d68d7c4

@meta-cla meta-cla bot added the CLA Signed label Feb 4, 2026
@eps1lon eps1lon changed the title [Flight] Fix dev-only crash when nesting 3rd party components [Flight] Fix dev-only crash when passing elements into 3rd party renderers Feb 5, 2026
unstubbable added a commit to unstubbable/react that referenced this pull request Feb 9, 2026
`encodeReply` throws "React Element cannot be passed to Server Functions
from the Client without a temporary reference set" when a React element
is the root value of a `serializeModel` call (either passed directly or
resolved from a promise), even when a temporary reference set is
provided.

The cause is that `resolveToJSON` hits the `REACT_ELEMENT_TYPE` switch
case before reaching the `existingReference`/`modelRoot` check that
regular objects benefit from. The synthetic JSON root created by
`JSON.stringify` is never tracked in `writtenObjects`, so
`parentReference` is `undefined` and the code falls through to the
throw. This adds a `modelRoot` check in the `REACT_ELEMENT_TYPE` case,
following the same pattern used for promises and plain objects.

The added `JSX as root model` test also uncovered a pre-existing crash
in the Flight Client: when the JSX element round-trips back, it arrives
as a frozen object (client-created elements are frozen in DEV), and
`Object.defineProperty` for `_debugInfo` fails because frozen objects
are non-configurable. The same crash can occur with JSX exported as a
client reference. For now, we're adding `!Object.isFrozen()` guards in
`moveDebugInfoFromChunkToInnerValue` and `addAsyncInfo` to prevent the
crash, which means debug info is silently dropped for frozen elements.
The proper fix would likely be to clone the element so each rendering
context gets its own mutable copy with correct debug info.

closes facebook#34984
closes facebook#35690
unstubbable added a commit to unstubbable/react that referenced this pull request Feb 9, 2026
`encodeReply` throws "React Element cannot be passed to Server Functions
from the Client without a temporary reference set" when a React element
is the root value of a `serializeModel` call (either passed directly or
resolved from a promise), even when a temporary reference set is
provided.

The cause is that `resolveToJSON` hits the `REACT_ELEMENT_TYPE` switch
case before reaching the `existingReference`/`modelRoot` check that
regular objects benefit from. The synthetic JSON root created by
`JSON.stringify` is never tracked in `writtenObjects`, so
`parentReference` is `undefined` and the code falls through to the
throw. This adds a `modelRoot` check in the `REACT_ELEMENT_TYPE` case,
following the same pattern used for promises and plain objects.

The added `JSX as root model` test also uncovered a pre-existing crash
in the Flight Client: when the JSX element round-trips back, it arrives
as a frozen object (client-created elements are frozen in DEV), and
`Object.defineProperty` for `_debugInfo` fails because frozen objects
are non-configurable. The same crash can occur with JSX exported as a
client reference. For now, we're adding `!Object.isFrozen()` guards in
`moveDebugInfoFromChunkToInnerValue` and `addAsyncInfo` to prevent the
crash, which means debug info is silently dropped for frozen elements.
The proper fix would likely be to clone the element so each rendering
context gets its own mutable copy with correct debug info.

closes facebook#34984
closes facebook#35690
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants