Invalid state: ReadableStream is already closed
Hello here, I am starting to suspect something odd in @hono/node-server
We have random ReadableStream is already closed in the app, everything is try/catch but anyway it crashes the container.
We are also using GraphQL Yoga, I found out about this: https://github.com/honojs/node-server/issues/77
But I hesitate to do that because GraphQL Yoga is using @whatwg-node/fetch which is supposed to be a good abstraction.
the full trace is:
node:internal/webstreams/readablestream:1162
throw new ERR_INVALID_STATE.TypeError('ReadableStream is already closed');
^
TypeError [ERR_INVALID_STATE]: Invalid state: ReadableStream is already closed
at ReadableByteStreamController.close (node:internal/webstreams/readablestream:1162:13)
at node:internal/deps/undici/undici:1480:28
at node:internal/process/task_queues:151:7
at AsyncResource.runInAsyncScope (node:async_hooks:211:14)
at AsyncResource.runMicrotask (node:internal/process/task_queues:148:8)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
code: 'ERR_INVALID_STATE'
}
Node.js v22.13.1
Of course I don't reproduce easily, it happens randomly
Any idea? to identify the problem better?
could it be related to this: https://github.com/honojs/node-server/blob/main/src/request.ts#L76
but it's so random (we have hundred of thousand request that are OK)
Hi @Plopix. Thank you for the report. I will investigate.
After thinking about it for a while, I think it would be better to catch it by ‘uncaughtException’ as follows.
process.on('uncaughtException', (err) => {
console.error('uncaughtException:', err);
});
Where did the error occur?
The following areas are related, and it is due to a race condition in the loading and disconnecting of the response body.
https://github.com/nodejs/node/blob/v22.13.1/deps/undici/undici.js#L1480 https://github.com/nodejs/node/blob/v22.13.1/deps/undici/undici.js#L5578
Because it is an error in queueMicrotask(), I think Hono and node-server (this project) cannot catch the exception.
If this problem can be solved using the Node.js native APIs in GraphQL Yoga, I think it would be good to consider it.