@samitouri / QOS-React-2 / commits / 2f0e7e570d

[Flight] Don't block on debug channel if it's not wired up (#33757)

React Elements reference debug data (their stack and owner) in the debug channel. If the debug channel isn't wired up this can block the client from resolving. We can infer that if there's no debug channel wired up and the reference wasn't emitted before the element, then it's probably because it's in the debug channel. So we can skip it. This should also apply to debug chunks but they're not yet blocking until #33665 lands.

Sebastian Markbåge committed Jul 15, 2025 at 11:45 UTC 2f0e7e570d3a99adc2a18e7575d1d2bb69660e1f
1 file changed +20
packages/react-client/src/ReactFlightClient.js
+20
@@ -1353,6 +1353,26 @@ function waitForReference<T>(
1353 map: (response: Response, model: any, parentObject: Object, key: string) => T,
1354 path: Array<string>,
1355 ): T {
1356 + if (
1357 + __DEV__ &&
1358 + // TODO: This should check for the existence of the "readable" side, not the "writable".
1359 + response._debugChannel === undefined
1360 + ) {
1361 + if (
1362 + referencedChunk.status === PENDING &&
1363 + parentObject[0] === REACT_ELEMENT_TYPE &&
1364 + (key === '4' || key === '5')
1365 + ) {
1366 + // If the parent object is an unparsed React element tuple, and this is a reference
1367 + // to the owner or debug stack. Then we expect the chunk to have been emitted earlier
1368 + // in the stream. It might be blocked on other things but chunk should no longer be pending.
1369 + // If it's still pending that suggests that it was referencing an object in the debug
1370 + // channel, but no debug channel was wired up so it's missing. In this case we can just
1371 + // drop the debug info instead of halting the whole stream.
1372 + return (null: any);
1373 + }
1374 + }
1375 +
1376 let handler: InitializationHandler;
1377 if (initializingHandler) {
1378 handler = initializingHandler;