[FlightReply] Don't drop FormData entries in `decodeReplyFromBusboy` (#36468)
Fixes a regression from #36425 where referenced `FormData` entries can
be dropped by `decodeReplyFromBusboy` when files are interleaved with
text fields in the payload.
`decodeReplyFromBusboy` queues text fields that arrive while a file is
being streamed and flushes them after the last file's `'end'`, working
around busboy emitting `'end'` deferred relative to subsequent `'field'`
events. With multiple files interleaved with text, this loses the
relative order of the affected text entries. The reorder was a
long-standing but invisible issue — entries came back in the wrong order
but were all present — until #36425 tightened how referenced FormData
entries are collected from the backing store to rely on them being
contiguous. With that assumption violated, referenced FormDatas can now
come back with some entries dropped. The pattern is most easily surfaced
through `useActionState` actions that return the submitted `FormData` as
part of their state.
This replaces the tail-flush with a linked list of pending files. Text
fields that arrive while a file is in flight are queued on the tail
file's `queuedFields`; fields that arrive when the list is empty resolve
immediately. `flush()` walks from the head, resolving each completed
file followed by its queued fields, and stops at the first file that
hasn't ended yet. The backing FormData now matches the payload's order,
restoring the contiguity assumption (and fixing the long-standing
reorder as a side effect). The same change is applied to all five copies
in `react-server-dom-{webpack,turbopack,parcel,esm,unbundled}`. Two new
tests cover the multi-file interleave.
fixes vercel/next.js#93822 H
Hendrik Liebau committed
b91823e21434ac665450e67ddc6f816710255938
Parent: f6790c1
Committed by GitHub <noreply@github.com>
on 5/14/2026, 8:03:52 PM