Bun.serve: apply TCP backpressure to a request body the handler reads slowly - #36006
Merged
Jarred-Sumner merged 15 commits intoJul 27, 2026
Merged
Claude / Claude Code Review
completed
Jul 26, 2026 in 36m 56s
Code review found 2 important issues
Found 2 candidates, confirmed 2. See review comments for details.
Details
| Severity | Count |
|---|---|
| 🔴 Important | 2 |
| 🟡 Nit | 0 |
| 🟣 Pre-existing | 0 |
| Severity | File:Line | Issue |
|---|---|---|
| 🔴 Important | src/runtime/server/RequestContext.rs:4083-4088 |
Bun.write(file, req) in a Bun.serve handler hangs for request bodies > 1 MiB |
| 🔴 Important | src/runtime/server/RequestContext.rs:1189-1190 |
resume_request_body_socket() in end_already_responded_stream may dereference a freed uWS socket |
Annotations
Check failure on line 4088 in src/runtime/server/RequestContext.rs
claude / Claude Code Review
Bun.write(file, req) in a Bun.serve handler hangs for request bodies > 1 MiB
`await Bun.write(file, req)` in a `Bun.serve` handler now hangs for any body > 1 MiB. That path (Blob.rs:5232-5250, `BodyValue::Locked` → `WriteFileWaitFromLockedValueTask`) sets `locked.on_receive_value` and awaits the last chunk without calling `on_start_buffering` or creating a ByteStream, so `REQUEST_BODY_BUFFER_ALL` is never set, the pre-stream HWM check pauses the socket at 1 MiB, and nothing ever resumes it — same bug class as the `buffer_action` deadlock adf72bd fixed, on the `on_receive
Check failure on line 1190 in src/runtime/server/RequestContext.rs
claude / Claude Code Review
resume_request_body_socket() in end_already_responded_stream may dereference a freed uWS socket
The fix in adf72bd added `resume_request_body_socket()` to `end_already_responded_stream()`, but this function's own doc comment (lines 1170-1178) states that `self.resp` may point to a socket uSockets has **already freed** via `us_internal_free_closed_sockets` and must be released *without dereferencing it*. When `REQUEST_BODY_PAUSED` is set, `resp.resume_()` → `us_socket_resume(s)` reads `s->fin_deferred` (socket.c:852, libuv) / `s->flags.is_paused` (:857) on freed memory, and `HttpResponse::r
Loading