#16474·Jest

[Bug]: intermittant "Unable to check memory usage Error: write EPIPE" when running one test when workerIdleMemoryLimit option is set

Author: lukpsaxoCreated Sep 29, 2026Updated Sep 29, 2026
LabelsNeeds TriageBug Report

Version

30.5.2

Steps to reproduce

// package.json
{ "jest": { "workerIdleMemoryLimit": "1024mb" } }
// a.test.js
test('a', () => expect(1).toBe(1));
for i in $(seq 1 20); do npx jest 2>&1 | grep -c EPIPE; done

this reproduces for me 30% of the time

Expected behavior

No error output when workers shut down normally.

Actual behavior

The tests pass and the exit code is 0, but Jest prints this one or more times (once per affected worker):

Unable to check memory usage Error: write EPIPE
    at target._send (node:internal/child_process:900:20)
    at target.send (node:internal/child_process:775:19)
    at ChildProcessWorker.checkMemoryUsage (node_modules/jest-worker/build/index.js:1068:19)
    at ChildProcessWorker._onProcessEnd (node_modules/jest-worker/build/index.js:984:16)
    at ChildProcessWorker._onExit (node_modules/jest-worker/build/index.js:965:14)
    at ChildProcess.emit (node:events:509:28)
    at ChildProcess._handle.onexit (node:internal/child_process:295:12) {
  errno: -32,
  code: 'EPIPE',
  syscall: 'write'
}

Additional context

The cause is a shutdown race in ChildProcessWorker:

WorkerPool.end() sends CHILD_MESSAGE_END through worker.send(), which stores the message in this._request as a request awaiting a reply. The child answers END by exiting, with no reply, so _onExit finds _request still set and calls _onProcessEnd. _onProcessEnd sees hasRequest, sees an idle memory limit and sees this._child.connected still true, so it calls checkMemoryUsage(). That writes to a closed IPC channel, which gives EPIPE. It only happens sometimes because Node can emit the child's exit before disconnect. When disconnect comes first, connected is already false and the send is skipped.

Possible fix: skip the memory check (and the _idleMemoryLimit === 0 restart) when the pending request is CHILD_MESSAGE_END. Alternatively, don't track END as a request at all.

Related: --runInBand avoids the error because no workers are used. Note that with workerIdleMemoryLimit set, Jest never chooses in-band mode on its own, even for a single test file, so these users hit worker shutdown on every run.

Environment

bash
System:
    OS: Linux 5.15 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat)
    CPU: (32) x64 Intel(R) Core(TM) i9-14900
  Binaries:
    Node: 24.18.0 - /home/dev/.nvm/versions/node/v24.18.0/bin/node
    Yarn: 4.18.1 - /mnt/c/npm/prefix/yarn
    npm: 11.16.0 - /home/dev/.nvm/versions/node/v24.18.0/bin/npm
  npmPackages:
    jest: 30.5.2 => 30.5.2