[Flight] Fix RangeError from exponential debug info growth (#37481)
The Flight Client copies the debug info of a referenced chunk into the chunk that references it, so that the receiving chunk records what blocked it. It copies the entries once per reference, and a referenced chunk already carries the entries that it received itself. A response that deduplicates the same object across a chain of rows therefore multiplies the entries at every step. In development the array eventually grows past what the engine can allocate for it, and the client throws `RangeError: Invalid array length`. The receiving chunk now takes each entry only once. The entries are copied by reference and never cloned on this path, so a comparison by identity is exact. The array becomes bounded by the number of distinct entries in the response rather than by a chosen limit. The bookkeeping costs one `Set` per chunk that receives debug info, in development only. The set holds a reference to each entry rather than a copy, so the entries stay shared and nothing about the debug info is duplicated. A chunk receives entries only while it is blocked, so the fix releases the set as soon as the chunk initializes. Debug info still accumulates transitively, which this change does not alter. This change also adds the `!reference.isDebug` guards that #37358 proposes for the element props branch and the default branch of `fulfillReference`. #35795 introduced the rule that a reference resolved during debug info resolution does not transfer, and it left those two branches behind. The guards make that rule hold at every branch. However, those branches reference debug chunks that carry no entries, so the guards change no observed behaviour, and they do not fix the growth in #37343, which comes from references in model chunks. #37343 also reports the call in `getOutlinedModel` as unguarded, which it is not, because #35795 already skips it there. The rest of #37358 deduplicates the entries, which is the right direction, but it scans the receiving array for every candidate, which is quadratic in the size of the debug info. #37359 caps the array at a constant instead, which stops the crash but keeps copying the duplicates and drops debug info once a response passes the cap. **Alternatives Considered** - Tracking the referenced chunks rather than the entries would be cheaper, because it would need one map entry per referenced chunk. It would not be enough, because a chunk can reach the same entry through two paths. A chunk can hold a client reference directly and also reference a chunk that already received the debug info of that client reference. - Recording the last receiving chunk on each entry would be exact while a chunk parses its model, where the transfers into it are consecutive. It would break once transfers into different chunks interleave, and that is the path the reported crash takes. - Turning `_debugInfo` itself into a `Set` is not possible, because the reconciler, Fizz, the Flight Server and DevTools read it by index and depend on its order. Fixes #37343 Closes #37358 Closes #37359 Co-authored-by: sundeep8967 <71071718+sundeep8967@users.noreply.github.com>
H
Hendrik Liebau committed
8f0043721ef508420ae3855d8e9f910b1fec1c85
Parent: 33b4555
Committed by GitHub <noreply@github.com>
on 9/2/2026, 1:57:40 PM