cloudflare / cloudflare/workerd
🐛 Bug Report — Runtime APIs: piping `ReadableStream` to an `IdentityTransformStream` results in uncaught `TypeError: This WritableStream has been closed.`
- Dominant language
- C++
- Stars
- 8.7k
- Forks
- 739
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 174
Description
Hey! 👋 With the following `workerd` configuration...
```capnp
using Workerd = import "/workerd/workerd.capnp";
const config :Workerd.Config = (
services = [
( name = "main", worker = .worker ),
],
sockets = [
( name = "http", address = "*:8080", http = (), service = "main" ),
]
);
const worker :Workerd.Worker = (
modules = [
( name = "index.mjs", esModule = embed "index.mjs" )
],
compatibilityDate = "2023-08-01",
);
```
```js
// index.mjs
export default {
async fetch(request, env, ctx) {
const readable = new ReadableStream({
pull(controller) {
controller.enqueue(new TextEncoder().encode("abc"));
controller.close();
}
});
const identity = new IdentityTransformStream();
ctx.waitUntil(readable.pipeTo(identity.writable));
return new Response(identity.readable);
}
}
```
...and running `workerd serve config.capnp --verbose`, logs `Uncaught (in promise); exception = TypeError: This WritableStream has been closed.` on request.
Finding the error string and adding `KJ_DBG`s to all those places shows the error is coming from:
https://github.com/cloudflare/workerd/blob/9f56120ba310eab2247e45a139816e51981c7f8d/src/workerd/api/streams/internal.c%2B%2B#L814
Replacing `const readable = new ReadableStream(...);` with...
```js
const { readable, writable } = new TransformStream();
const writer = writable.getWriter();
void writer.write(encoder.encode("abc"));
void writer.close();
```
...also leads to the same error.
Replacing `new IdentityTransformStream()` with `new TransformStream()` fixes the issue.
Contributor guide
Assessment
This issue has not been assessed yet.