cloudflare / cloudflare/workerd
attempting to close `FixedLengthStream` throws `Error: Network connection lost.`
- Dominant language
- C++
- Stars
- 8.7k
- Forks
- 739
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 174
Description
### What versions & operating system are you using?
wrangler v4.70.0
### Please provide a link to a minimal reproduction
n/a
### Describe the Bug
I'm streaming a file from sender to receiver, using a durable object to connect the two and pass along the bytes. The issue is that attempting to `close()` the stream after a successful transfer throws the following error:
```
Error: Network connection lost.
```
Here's a snippet of the relevant parts of the durable object:
```ts
export default class TransferObject implements DurableObject {
stream ?:TransformStream;
close = async () :Promise => {
let err :Error | null = null;
try {
...
err = await this.stream.writable.close()
.then(() => null)
.catch((e) => toError(e));
if (err !== null) {
throw err;
}
return new OkayResponse();
}
catch (exception) {
return new ErrorResponse(exception);
}
};
transfer = async (request :Request) :Promise => {
let err :Error | null = null;
try {
...
const transfer = await this.storage.get(TRANSFER);
if (!this.stream) {
// this results in the error when closing
this.stream = new FixedLengthStream(transfer.size);
// this is ok
// this.stream = new IdentityTransformStream();
}
err = await request.body
.pipeTo(this.stream.writable, { preventClose: true })
.then(() => null)
.catch((e) => toError(e));
if (err !== null) {
throw err;
}
return new OkayResponse();
}
catch (exception) {
return new ErrorResponse(exception);
}
};
}
```
When the receiver connects, the sender starts the transfer, which initializes a `TransformStream`, specifically `FixedLengthStream` set to the size of the file, and repeatedly calls `/transfer` for every chunk, . When all the bytes have been sent, the sender then calls `/close`, which attempts to close the `writable` stream.
If I initialize `FixedLengthStream(transfer.size + 1)`, then I correctly see this error:
```
FixedLengthStream did not see all expected bytes before close().
```
Similarly, if I initialize `FixedLengthStream(transfer.size - 1)`, then I correctly see this error:
```
TypeError: Attempt to write too many bytes through a FixedLengthStream.
```
It's just when the stream is initialized with the exact file size is when the `Error: Network connection lost.` error is thrown.
Using `IdentityTransformStream` instead of `FixedLengthStream` works as expected, no error is thrown.
Also notable, this is only happening in production. Running `wrangler` locally also works as expected, no error is thrown.
I've tried looking through the source code in https://github.com/cloudflare/workerd to better understand if there's undocumented implementation details around auto-closing instances of `FixedLengthStream` once all the bytes have been seen ... no luck so far.
### Please provide any relevant error logs
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.