#4247 R2 bindings `.put` fails with 500 with wrangler's `unstable_dev`
Duplicate of #6425 which has more engagement (8 comments) and better diagnosis. Root cause is workerd runtime requiring known-length streams for R2 ops.
Close as duplicate of #6425
Analysis Report
Issue Review: cloudflare/workers-sdk#4247
Summary
R2 bindings .put fails with 500 error when passing request.body ReadableStream via unstable_dev in Jest tests.
Findings
- Created: 2023-10-20
- Updated: 2025-10-30
- Version: 3.14.0 → 4.60.0 (current)
- Component: wrangler/R2/miniflare
- Labels: bug
- Comments: 0
Key Evidence
Bug still reproduces on wrangler 4.60.0 with a slightly different error message:
- Original error (2023):
Can't read from request stream after response has been sent - Current error (2026):
Provided readable stream must have a known length (request/response body or readable half of FixedLengthStream)
- Original error (2023):
Duplicate/Related issues exist:
- #6425 (Aug 2024): "R2ObjectBody body
ReadableStreamnot valid for put parameter" - Same error, same root cause - #4373 (Jun 2023): "[Miniflare] Consider buffering all requests" - Upstream tracking issue
- #6504 (Aug 2024): "
getPlatformProxydoes not accept NodeReadableStreams"
- #6425 (Aug 2024): "R2ObjectBody body
Root cause analysis (from #6425 comments):
- Error originates from workerd runtime, not workers-sdk
- The workerd RPC requires known length for R2 operations
- Workaround: Use
FixedLengthStreamwrapper or buffer the content to a string first
No fix PRs found directly referencing #4247 or addressing this underlying issue.
No changelog entries mentioning this issue number.
Recommendation
Status: CLOSE (as duplicate)
Reasoning: This issue is a duplicate of #6425, which was filed later (Aug 2024) but has more engagement (8 comments), better diagnosis of the root cause, and includes workarounds. The underlying issue is a limitation in workerd/miniflare that requires ReadableStreams to have a known length for R2 put operations. Both issues describe the same fundamental bug.
Action: Close as duplicate of #6425, which is the more active and better-documented tracking issue for this problem.
Suggested Comment
Thank you for reporting this issue. After investigation, this appears to be a duplicate of #6425, which tracks the same underlying problem: R2's
.put()operation in local development (via miniflare/workerd) requires ReadableStreams to have a known length.The root cause is in the workerd runtime, not workers-sdk specifically. Workarounds include:
- Buffering the content first:
const text = await request.text(); await env.BUCKET.put(key, text);- Using
FixedLengthStreamto wrap streams with known sizesI'm closing this as a duplicate - please follow #6425 for updates on this issue.