Problem
When using tinypool with pool: 'forks' and forceExit: true on Node v24, the child process IPC channel closes before tinypool finishes draining its message queue. This causes an unhandled ERR_IPC_CHANNEL_CLOSED error during teardown, even though all work has already completed successfully.
This is reproducible via Vitest (which uses tinypool internally) with:
pool: 'forks'
forceExit: true
- Node v24.x
Stack trace
Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
at ProcessWorker (tinypool/dist/index.js)
Workaround
Adding an error handler to the child process that ignores this specific error:
// In ProcessWorker constructor (dist/index.js)
this.process.on("error", (err) => {
if (err && err.code === "ERR_IPC_CHANNEL_CLOSED") return;
throw err;
});
Expected behavior
Tinypool should gracefully handle IPC channel closure during teardown when all tasks have completed, rather than throwing an unhandled error.
Environment
- tinypool: 1.1.1 (also not fixed in 2.1.0)
- Node: v24.x
- OS: macOS (also reproducible on Linux)
- Vitest: 3.x with forks pool
Problem
When using tinypool with
pool: 'forks'andforceExit: trueon Node v24, the child process IPC channel closes before tinypool finishes draining its message queue. This causes an unhandledERR_IPC_CHANNEL_CLOSEDerror during teardown, even though all work has already completed successfully.This is reproducible via Vitest (which uses tinypool internally) with:
pool: 'forks'forceExit: trueStack trace
Workaround
Adding an error handler to the child process that ignores this specific error:
Expected behavior
Tinypool should gracefully handle IPC channel closure during teardown when all tasks have completed, rather than throwing an unhandled error.
Environment