What This Error Means
npm hit EPIPE because it tried to write output to a closed pipe or terminated process, often in CI logs or shell pipelines.
How to Fix It
If you are piping output, remove the pipe and run npm directly (do not pipe to head/tail).
If this happens only in CI, try npm ci instead of npm install (requires package-lock.json).
Compare Node/npm versions between local and CI:node -v and npm -v
Retry with less output:npm --silent (or remove verbose logging).
If your CI runs as root, and lifecycle scripts are involved, test with npm install --unsafe-perm (CI-only, understand the risk).
Why It Happens
The command output is being piped to another process that exits early (example:npm ... | head).
A CI runner/log wrapper closed the output stream while npm was still writing logs.
The process was interrupted while writing output (less common, but possible).
How to Verify
Re-run the same command without piping output and confirm EPIPE is gone.
If you switched to npm ci, confirm the install completes reliably in CI.
Manual output and pipe checks
Check whether the failing command is being run with output piping or a log wrapper.
Re-run interactively (or via SSH) on the same machine and compare behavior.
Examples
npm ERR! code EPIPE
errorHandler({ errno: 'EPIPE' })
if (er.errno === 'EPIPE') { How npm writes output
EPIPE is a generic OS error that means a write was attempted on a closed pipe or socket.
In practice, this usually happens when stdout/stderr is closed by the parent process while npm is logging.
Prevention Tips
Prefer npm ci in CI for clean deterministic installs.
Avoid piping npm output to commands that terminate early.
Keep Node and npm versions consistent between environments.
Where This Can Be Triggered
github.com/npm/cli/blob/417daa72b09c5129e7390cd12743ef31bf3ddb83/lib/commands/completion.js
Open-source npm CLI code path where this error is raised. - GitHub
// can never ever work on OS X.
// TODO Ignoring coverage, see 'non EPIPE errors cause failures' test.
/* istanbul ignore next */
if (er.errno === 'EPIPE') {
res()
} else {
rej(er)