Bug
Multipart.toPersisted (and Multipart.persisted in @effect/platform-bun) hangs indefinitely when the multipart parser's maxTotalSize limit is exceeded mid-file during upload.
The request times out at 60s because the handler never completes — no response is ever sent.
Root Cause
This is caused by a bug upstream in multipasta (the multipart parsing library): the write() function returns early without forwarding the chunk to the boundary scanner when maxTotalSize is exceeded.
The chain:
- multipasta's
write() (src/internal/multipart.ts) checks maxTotalSize before split.write(). When exceeded, it calls onError and returns — the boundary scanner never sees the chunk.
- multipasta's web wrapper (
src/web.ts): the onFile callback sets finished only when onChunk(null) is called. This never happens because the scanner never processes the boundary ending the current file part.
@effect/platform-bun's persisted (dist/esm/internal/multipart.js:18-44): calls reader.readMany() in a loop waiting for the file's readable stream to close. It never does → hang.
@effect/platform's toPersisted: uses Stream.runForEach which awaits the writer callback for each part sequentially. So the outer stream's MultipartError is never observed — the handler never completes, no response is sent.
Key Distinction
| Limit |
Effect |
maxPartSize (per-file) |
Error fires, but file readable closes normally — chunk was already forwarded to scanner |
maxTotalSize (whole-request) |
Error fires, but file readable hangs — scanner never sees trailing boundary |
Upstream Fix
The fix is in multipasta: tim-smart/multipasta#38 — the write() method should still forward the chunk to split.write() after calling onError, so the boundary scanner can close the current file part's readable.
Once multipasta is fixed, @effect/platform-bun will need to bump the multipasta dependency.
Bug
Multipart.toPersisted(andMultipart.persistedin@effect/platform-bun) hangs indefinitely when the multipart parser'smaxTotalSizelimit is exceeded mid-file during upload.The request times out at 60s because the handler never completes — no response is ever sent.
Root Cause
This is caused by a bug upstream in multipasta (the multipart parsing library): the
write()function returns early without forwarding the chunk to the boundary scanner whenmaxTotalSizeis exceeded.The chain:
write()(src/internal/multipart.ts) checksmaxTotalSizebeforesplit.write(). When exceeded, it callsonErrorand returns — the boundary scanner never sees the chunk.src/web.ts): theonFilecallback setsfinishedonly whenonChunk(null)is called. This never happens because the scanner never processes the boundary ending the current file part.@effect/platform-bun'spersisted(dist/esm/internal/multipart.js:18-44): callsreader.readMany()in a loop waiting for the file's readable stream to close. It never does → hang.@effect/platform'stoPersisted: usesStream.runForEachwhich awaits the writer callback for each part sequentially. So the outer stream'sMultipartErroris never observed — the handler never completes, no response is sent.Key Distinction
maxPartSize(per-file)maxTotalSize(whole-request)Upstream Fix
The fix is in multipasta: tim-smart/multipasta#38 — the
write()method should still forward the chunk tosplit.write()after callingonError, so the boundary scanner can close the current file part's readable.Once multipasta is fixed,
@effect/platform-bunwill need to bump the multipasta dependency.