Skip to content

fix: ignore epilogue after closing multipart boundary - #229

Closed
kilisamemarisaaa wants to merge 2 commits into
fastify:mainfrom
kilisamemarisaaa:codex/fix-epilogue-write-hang
Closed

kilisamemarisaaa wants to merge 2 commits into
fastify:mainfrom
kilisamemarisaaa:codex/fix-epilogue-write-hang

Conversation

@kilisamemarisaaa

@kilisamemarisaaa kilisamemarisaaa commented Aug 31, 2026 •

Copy link
Copy Markdown

Summary

  • ignore epilogue chunks that arrive after Dicer has recognized the closing multipart boundary
  • complete the outer write callback instead of waiting forever for a drain from a finished parser
  • add a Busboy-level regression test for an epilogue delivered in a later event-loop turn

Fixes #228.

Root cause

After the closing boundary, Dicer marks itself finished and resets its internal boundary parser. Once pending parts have ended, the multipart wrapper also ends Dicer. A later Busboy write still called parser.write() on that completed Dicer. The call returned false, so Multipart stored the outer callback while waiting for a drain event that can never occur. As a result, Busboy.end() stayed queued and finish was never emitted.

The write path now ignores bytes only when Dicer's closing-boundary state is set. Other non-writable states, such as a parser destroyed before the closing boundary, are not mistaken for epilogue. The regression test also verifies field -> epilogue write callback -> finish ordering and a single finish event.

Reproduction

On unmodified main (4e8de12), a complete body followed by epilogue in the same chunk emitted field=value and finish. Writing that same epilogue after setImmediate emitted the field but still had finish=false and no error after 200 ms.

Validation

  • npm test: 237 unit tests passed with 100% statement, branch, function, and line coverage; 101 type assertions passed
  • npm run lint
  • node --test test/types-multipart-coverage.test.js: 9 passed
  • Windows 11, Node.js 24.12.0

@Fdawgs Fdawgs closed this Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finish is never emitted when bytes arrive after the closing boundary in a separate write

2 participants