Skip to content

fix: propagate client disconnects to response body streams#93906

Open
coffeeispower wants to merge 2 commits into
vercel:canaryfrom
coffeeispower:fix-client-disconnection
Open

fix: propagate client disconnects to response body streams#93906
coffeeispower wants to merge 2 commits into
vercel:canaryfrom
coffeeispower:fix-client-disconnection

Conversation

@coffeeispower
Copy link
Copy Markdown

@coffeeispower coffeeispower commented May 17, 2026

What?

Fixes response stream cancellation when the client disconnects before the response body finishes streaming.

Why?

Long-lived streaming responses need their body stream to be cancelled when the client connection is closed. Without that cancellation, application cleanup logic attached to the stream may not run, which can leave per-client resources alive after the client has gone away even if the app has registered a event listener using request.signal.addEventListener("abort", ...)

This was found while building Radiant, a TypeScript web app for creating radios that you can schedule playlists, songs, ad sections and other things and it serves long-lived ICY/audio streams from Next.js route handlers. Each listener connection owns stream resources and registers cleanup logic that must run when the client disconnects.

In the real reproduction case, connecting with mpv and then closing the player aborted the HTTP response, but the response body stream was not cancelled. The route returned, but the stream finalizer responsible for removing the listener from the radio runtime did not run until this piping path was patched to propagate the disconnect to the body stream.

This is not only specific to audio: the same issue can affect any long-lived response body stream that relies on cancellation/finalizers for cleanup, such as event streams, proxy streams, or custom streaming route handlers.

How?

The response piping path now propagates client aborts to the response body stream. It also avoids surfacing noisy double-close errors when the writable side has already been closed or errored during disconnect cleanup.

Comment thread packages/next/src/server/pipe-readable.ts
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.

1 participant