cloudflare / cloudflare/workerd

🐛 Bug Report — Runtime APIs: piping `ReadableStream` to an `IdentityTransformStream` results in uncaught `TypeError: This WritableStream has been closed.`

Open
#992 7 comments 6 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.