Skip to content

[Flight] Fix isValidElement returning false for elements with a debug channel#36136

Open
976520 wants to merge 1 commit intofacebook:mainfrom
976520:fix/flight-isvalidelement-debug-channel
Open

[Flight] Fix isValidElement returning false for elements with a debug channel#36136
976520 wants to merge 1 commit intofacebook:mainfrom
976520:fix/flight-isvalidelement-debug-channel

Conversation

@976520
Copy link

@976520 976520 commented Mar 24, 2026

Summary

When debugChannel with a readable stream is provided to createFromNodeStream,
positions 4 (owner) and 5 (stack) in RSC element tuples reference pending debug
chunks. The previous code tracked these as blocking deps, which caused elements to
be wrapped in REACT_LAZY_TYPE via createLazyChunkWrapper — breaking
isValidElement(), cloneElement(), and hydration checks.

Fix: Track debug-only deps (positions 4/5 with an active debug channel) separately
in a new debugDeps counter on InitializationHandler. Only lazy-wrap when there
are real blocking deps beyond debug-only ones. After all debug deps resolve, call
initializeElement() again so _debugStack gets normalized from the raw serialized
string into an Error object, which is required by captureOwnerStack /
formatOwnerStack.

Fixes #36097

How did you test this change?

Added a regression test in ReactFlightDOMNode-test.js that reproduces the bug:
renders a server component through a debugChannel-backed stream with a delayed
transport, deserializes the result, and asserts React.isValidElement(deserialized) === true.

Also verified the existing "can transport debug info through a slow debug channel"
test continues to pass — the owner stack captured during SSR still correctly reflects
the server-side owner even with the delayed debug channel.

… channel

When `debugChannel` with a readable stream is provided to
`createFromNodeStream`, positions 4 (owner) and 5 (stack) in RSC element
tuples reference pending debug chunks. The previous code tracked these as
blocking deps, which caused elements to be wrapped in `REACT_LAZY_TYPE`
via `createLazyChunkWrapper` — breaking `isValidElement()`,
`cloneElement()`, and hydration checks.

Track debug-only deps (positions 4/5 with an active debug channel)
separately in a new `debugDeps` counter on `InitializationHandler`. Only
lazy-wrap when there are real blocking deps beyond debug-only ones. After
all debug deps resolve, call `initializeElement()` again so `_debugStack`
gets normalized from the raw serialized string into an `Error` object,
which is required by `captureOwnerStack` / `formatOwnerStack`.

Fixes facebook#36097
@meta-cla meta-cla bot added the CLA Signed label Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Flight Client wraps elements in lazy chunks when debugChannel is enabled, causing isValidElement() to return false

1 participant