Skip to content

Fix: npm ERR! code ELIFECYCLE (errno 1, Failed at script)

FixDevs · (Updated: )

Part of:  JavaScript & TypeScript Errors

Quick Answer

How to fix npm ERR! code ELIFECYCLE, npm ERR! errno 1, and npm ERR! Failed at the script errors. Covers reading the real error, node_modules corruption, node-gyp failures, wrong Node version, memory issues, postinstall failures, Windows-specific fixes, and more.

When npm Lies About Where the Problem Is

Personally, my biggest pet peeve about ELIFECYCLE is that the name suggests an npm bug when the real error is always one of the dependency’s exit codes. The fix is rarely in npm; it is in whatever script the lifecycle runner invoked. I have trained myself to scroll PAST the npm ERR! block before reaching for any tool. You run npm run build, npm install, or npm test and get:

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! my-app@1.0.0 build: `react-scripts build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the my-app@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

The key line is: “This is probably not a problem with npm.” npm is telling you that the script it tried to run exited with an error. ELIFECYCLE is just the wrapper. The real error is somewhere above this block in your terminal output.

You might also see variations like:

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! code ELIFECYCLE
npm ERR! errno 137

The errno tells you how the process exited. 1 is a generic failure. 2 usually means misuse of a shell command. 137 means the process was killed (out of memory). Each one points to a different root cause.

Quick Reference Before You Dive In

If you arrived here from Google with a fresh ELIFECYCLE, the five facts that resolve roughly 90 percent of cases:

  1. ELIFECYCLE means “a script exited non-zero.” It is NOT an npm bug. The actual error is somewhere ABOVE the npm ERR! block in your terminal. The npm lifecycle scripts documentation and the npm run command reference are the canonical sources.
  2. The errno tells you the failure category. 1 = generic failure (read the script’s actual error), 2 = shell misuse (Windows-vs-Unix syntax), 137 = OOM kill (raise --max-old-space-size).
  3. rm -rf node_modules package-lock.json && npm install solves a surprising fraction of cases. Corrupted node_modules is the second-most-common cause after script errors.
  4. gyp ERR! in the output means a native module failed to COMPILE. You need build tools (Xcode CLT on macOS, build-essential on Debian / Ubuntu, Visual Studio Build Tools on Windows).
  5. In CI especially, raise NODE_OPTIONS=--max-old-space-size=4096 if errno is 137. The kernel OOM-killed Node; this is not an npm or script bug.

The rest of this article walks through each cause in detail, plus the failure modes most other guides skip.

How npm Wraps Script Failures into ELIFECYCLE

ELIFECYCLE means an npm lifecycle script (like build, start, test, postinstall, or prepare) exited with a non-zero status code. npm ran a command, that command failed, and npm reported the failure.

The error is never about npm itself. It is always about what the script tried to do. The most common underlying causes:

  • Your build or start script has a code error. A syntax error, a missing import, a failed compilation. The real error message is printed above the ELIFECYCLE block.
  • node_modules is corrupted. A previous install was interrupted, a package was partially downloaded, or your lockfile is out of sync.
  • node-gyp can’t compile a native module. A package with C/C++ bindings (like bcrypt, sharp, node-sass, sqlite3) failed to build because system dependencies are missing.
  • Wrong Node.js version. The package requires a specific Node.js version range and yours is outside it.
  • The build ran out of memory. Large projects (especially those using Webpack or TypeScript) can exceed Node.js’s default memory limit.
  • A postinstall or prepare script in a dependency failed. Some packages run build steps after installation.
  • Windows-specific issues. Path length limits, missing build tools, or shell incompatibilities.

When to Use Which Fix

The next sections cover the fixes in detail. The table below maps your situation to the recommended fix.

Your situationRecommended fixWhy
Have not read above the npm ERR! block yetFix 1: scroll up, find the real errorFirst step, always
Suspect corrupted installFix 2: rm -rf node_modules package-lock.json && npm installClean state
gyp ERR! in outputFix 3: install build toolsNative module compilation
engines mismatchFix 4: switch Node version with nvm / fnmRequired Node version differs
JavaScript heap out of memory or errno 137Fix 5: --max-old-space-size=4096Build runs out of memory
Fails during npm install (not run)Fix 6: --ignore-scripts or debug the postinstallDependency lifecycle script failed
.npmrc misconfiguredFix 7: npm config list, rename .npmrc and retestConfig can break scripts
Lockfile merge conflictsFix 8: regenerate package-lock.jsonStale lockfile after merge
Windows-specific issuesFix 9: long paths, Git Bash shell, VS Build ToolsWindows has unique quirks

If multiple rows apply, pick the topmost one.

Fix 1: Read the Actual Error Above ELIFECYCLE

This is the most important step and the one most people skip. Scroll up in your terminal. The real error is above the npm ERR! lines.

For example, you might see:

Module not found: Can't resolve './components/Header'
SyntaxError: Unexpected token '}'
error TS2307: Cannot find module '@/utils/helpers'
gyp ERR! build error

Each of these has a completely different fix. The ELIFECYCLE block is just npm saying “the script failed.” Your job is to find and fix the error the script reported.

If your terminal doesn’t show enough history, run the command again and pipe to a file:

npm run build 2>&1 | tee build-output.log

Then search the log for the first error. If the error is about a missing module, see Fix: Module not found: Can’t resolve.

A reading habit I have internalized: scroll past the npm ERR! block before doing anything else. The block at the bottom is npm announcing that a child process died; the actual error is always above. Most engineers I have shadowed who got stuck on ELIFECYCLE for an hour skipped this one step and went straight to reinstalling dependencies. One up-arrow press would have saved them the time.

Fix 2: Delete node_modules and Reinstall

Corrupted node_modules is behind a huge number of ELIFECYCLE failures. A broken install, an interrupted npm install, switching branches with different dependencies, or even a corrupted npm cache can all leave node_modules in a bad state.

Clean reinstall:

rm -rf node_modules package-lock.json
npm install

On Windows (Command Prompt):

rmdir /s /q node_modules
del package-lock.json
npm install

On Windows (PowerShell):

Remove-Item -Recurse -Force node_modules
Remove-Item package-lock.json
npm install

Deleting package-lock.json forces npm to resolve the entire dependency tree from scratch. If you need to preserve exact versions from your lockfile (e.g., in CI), delete only node_modules:

rm -rf node_modules
npm ci

npm ci is designed for clean installs. It deletes node_modules automatically and installs exactly what the lockfile specifies. It is faster than npm install and more reliable in CI environments.

If npm install itself fails with dependency conflicts, see Fix: npm ERR! ERESOLVE unable to resolve dependency tree.

Fix 3: Fix node-gyp Build Failures

If the error output contains gyp ERR!, a native module failed to compile. node-gyp compiles C/C++ addons and requires build tools to be installed on your system.

The error typically looks like:

gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! not ok
npm ERR! code ELIFECYCLE

On macOS

Install Xcode Command Line Tools:

xcode-select --install

On Ubuntu/Debian

sudo apt-get update
sudo apt-get install -y build-essential python3

On Windows

Windows requires the most setup. Install the build tools:

npm install -g windows-build-tools

Or install them manually:

  1. Install Visual Studio Build Tools with the “Desktop development with C++” workload.
  2. Install Python 3.x from python.org.
  3. Tell npm where to find Python:
npm config set python python3

If you’re using node-gyp v10+, Python 3.12+ is supported. Older versions of node-gyp may need Python 3.6-3.11.

After installing the build tools, rebuild:

npm rebuild

Or do a clean install:

rm -rf node_modules package-lock.json
npm install

Common native module alternatives

Some native modules have pure JavaScript alternatives that don’t require compilation:

Native ModuleAlternativeInstall
node-sasssass (Dart Sass)npm install sass
bcryptbcryptjsnpm install bcryptjs
sharp(no drop-in; use prebuilt binaries)npm install --include=optional sharp

If you’re hitting node-gyp errors with node-sass, switch to sass. node-sass is deprecated and consistently causes build problems:

npm uninstall node-sass
npm install sass

No code changes needed in most cases. Sass-loader and framework CLIs automatically use whichever Sass compiler is installed.

Fix 4: Use the Correct Node.js Version

Some packages require a specific Node.js version range. If you’re on the wrong version, builds can fail with cryptic errors that end in ELIFECYCLE.

Check what your project expects:

cat package.json | grep -A 2 '"engines"'

You might see:

{
  "engines": {
    "node": ">=18.0.0"
  }
}

Check your current version:

node -v

If there is a mismatch, switch using nvm:

nvm install 18
nvm use 18

Or with fnm:

fnm install 18
fnm use 18

If the project has an .nvmrc or .node-version file:

nvm use

After switching Node.js versions, always reinstall your dependencies. Native modules are compiled against a specific Node.js ABI, and they will not work across versions:

rm -rf node_modules package-lock.json
npm install

Fix 5: Increase Node.js Memory Limit

If the error output includes FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed or JavaScript heap out of memory, or if the errno is 137 (OOM killed), the build is running out of memory.

Node.js defaults to roughly 1.5 GB of heap memory. Large projects with big dependency trees, many source files, or complex Webpack/TypeScript compilations can exceed this.

Increase the limit:

export NODE_OPTIONS="--max-old-space-size=4096"
npm run build

On Windows (Command Prompt):

set NODE_OPTIONS=--max-old-space-size=4096
npm run build

On Windows (PowerShell):

$env:NODE_OPTIONS="--max-old-space-size=4096"
npm run build

You can also set it directly in your package.json script:

{
  "scripts": {
    "build": "node --max-old-space-size=4096 ./node_modules/.bin/react-scripts build"
  }
}

Or using the cross-platform cross-env package:

npm install --save-dev cross-env
{
  "scripts": {
    "build": "cross-env NODE_OPTIONS=--max-old-space-size=4096 react-scripts build"
  }
}

Common memory limit values:

  • 4096: 4 GB (handles most projects)
  • 8192: 8 GB (for very large monorepos or heavy TypeScript projects)

If even 8 GB is not enough, the problem is usually not memory. Look for circular dependencies, massive bundle sizes, or misconfigured build tools.

The same --max-old-space-size knob also tunes Vite, Next.js, and Webpack; they all run inside the Node process you launch, so the limit applies to every JS bundler in your toolchain.

A scenario I have personally debugged at least three times: CI passes on main, fails with ELIFECYCLE on a feature branch. Cause: the feature branch added a dependency requiring Node 18+, but the CI image runs Node 16. The fix is to bump the CI Node version (or pin the engines field) before merging. Adding "engines": { "node": ">=18" } to package.json makes the requirement explicit; a CI runner on the wrong version then errors with EBADENGINE, which is easier to diagnose than ELIFECYCLE wrapping a downstream syntax error.

Fix 6: Fix postinstall and prepare Script Failures

Sometimes ELIFECYCLE happens during npm install itself, not during npm run build. This means a package’s postinstall, prepare, or install lifecycle script failed.

The error looks like:

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! some-package@2.1.0 postinstall: `node scripts/build.js`
npm ERR! Exit status 1

Look at the package name in the error. It is not your project; it is a dependency that runs a build step after being installed.

Common fixes:

Skip optional dependencies that have postinstall scripts:

npm install --ignore-scripts

This skips all lifecycle scripts. Use it to get past the install, then manually run your project’s prepare/build steps. Be aware that some packages genuinely need their postinstall scripts (e.g., esbuild, sharp, puppeteer).

Install the specific package separately with more info:

npm install some-package --verbose

The verbose output will show exactly what the postinstall script tried to do and where it failed.

Skip scripts only for a specific package:

If you need most postinstall scripts to run but want to skip one, add it to your .npmrc:

ignore-scripts=false

Then override per-package in package.json:

{
  "scripts": {
    "preinstall": "npx only-allow npm"
  }
}

Or rebuild just the failing package after install:

npm install --ignore-scripts
npm rebuild some-package

Fix 7: Fix .npmrc and Configuration Issues

A misconfigured .npmrc can cause ELIFECYCLE errors. npm reads configuration from multiple locations, and conflicting settings can break installs.

Check your active configuration:

npm config list

This shows merged settings from all .npmrc files (project, user, and global). Look for anything unexpected, especially:

  • script-shell: Overrides the shell used to run scripts. If it points to a shell that doesn’t exist, every script will fail.
  • prefix: Changes where global packages are installed. A wrong prefix can cause path issues.
  • registry: Points to a custom registry. If the registry is down or unrequested auth is needed, installs fail.

Check for project-level .npmrc:

cat .npmrc

Check for user-level .npmrc:

cat ~/.npmrc

If you suspect .npmrc is the problem, temporarily rename it and try again:

mv .npmrc .npmrc.bak
npm install

Fix 8: Fix Lock File Conflicts

If you recently merged branches or pulled changes, your package-lock.json might have merge conflicts or stale entries. This can cause npm install to produce a broken node_modules, which then causes ELIFECYCLE when running scripts.

Signs of a lock file problem:

  • npm install succeeds but npm run build fails with missing modules
  • Git shows merge conflict markers (<<<<<<<) in package-lock.json
  • Different team members get different results from npm install

Fix:

rm package-lock.json
rm -rf node_modules
npm install

This regenerates the lock file from your package.json. Commit the new package-lock.json:

git add package-lock.json
git commit -m "Regenerate package-lock.json"

If you are using a .npmrc that sets package-lock=false, npm will not create a lock file at all. In that case, dependency resolution can vary between installs, which makes ELIFECYCLE errors less reproducible.

Fix 9: Windows-Specific Issues

Windows causes more ELIFECYCLE errors than macOS or Linux. Here are the Windows-specific problems and their fixes.

Path length limit

Windows has a 260-character path limit by default. Deeply nested node_modules directories can exceed it. npm 3+ uses a flat node_modules structure to mitigate this, but some packages still create deep nesting.

Enable long paths (requires admin privileges):

# Run PowerShell as Administrator
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force

Or enable it through Group Policy: Computer Configuration > Administrative Templates > System > Filesystem > Enable Win32 long paths.

Shell issues

npm uses cmd.exe by default on Windows to run scripts. Some scripts use Unix shell syntax (like &&, rm -rf, export) that does not work in cmd.exe.

Switch npm to use Git Bash:

npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"

Or use WSL (Windows Subsystem for Linux) to run your project in a Linux environment entirely.

node-gyp and Visual Studio

node-gyp on Windows requires:

  1. Visual Studio Build Tools (or full Visual Studio) with the “Desktop development with C++” workload
  2. Python 3.x

The most reliable way to install both:

npm install -g windows-build-tools

This may require an elevated (Administrator) terminal. If it stalls, install Python and Visual Studio Build Tools manually.

How Other Package Managers Handle Lifecycle Scripts

ELIFECYCLE is npm’s wrapper for “a lifecycle script exited non-zero.” Other Node package managers run the same scripts but with meaningfully different defaults around security, hook order, and error reporting. Knowing the differences matters when you swap managers in CI or inherit a project that mixed them.

npm 7+: Runs all lifecycle scripts (preinstall, install, postinstall, prepare) by default. From npm 9 onward, npm audit fix and npm install no longer auto-run scripts from transitive dependencies you do not control directly; but direct dependencies still execute their scripts. Failures surface as npm ERR! code ELIFECYCLE. The --ignore-scripts flag disables every lifecycle script in the install graph; it does not disable scripts in package.json you run yourself.

Yarn Classic (1.x): Similar behavior to npm; runs all lifecycle scripts by default. Failures print error Command failed with exit code N instead of ELIFECYCLE. Yarn 1 is in maintenance mode; the long-term path is Yarn Berry.

Yarn Berry (2+): Adds enableScripts: false per-package in .yarnrc.yml so you can allow scripts only from packages you explicitly trust. The default is still to run scripts, but the packageExtensions mechanism gives much finer-grained control than npm. Plug’n’Play mode also changes how scripts resolve binaries; Yarn intercepts require instead of writing node_modules.

pnpm: Runs preinstall, install, postinstall, and prepare by default, but disables scripts from transitive dependencies behind the side-effects-cache and the --ignore-scripts flag. As of pnpm 10, lifecycle scripts from transitive dependencies are blocked by default and require explicit allow-listing via onlyBuiltDependencies in package.json. This is the strictest default of the three managers; a supply-chain attack via a deep dependency’s postinstall is much harder to land in pnpm than in npm.

Bun: Runs lifecycle scripts for direct dependencies only by default. Transitive postinstall scripts are skipped unless the package is in trustedDependencies in your package.json. The error format is shorter; bun install prints error: lifecycle script "postinstall" exited with code 1 and stops. Bun’s runtime also executes scripts much faster because it does not spawn a separate Node process.

Hook order is roughly the same everywhere. All four run preinstall → install logic → installpostinstallprepare for the package being installed. The pre* / post* chain for your own scripts (prebuild, build, postbuild) is honored by npm, Yarn, and Bun but not by pnpm, which removed implicit pre/post for non-lifecycle scripts in pnpm 7+. If you migrate from npm to pnpm and your prebuild stops running, that is why; call the prebuild explicitly inside build.

ignore-scripts security defaults are diverging. The community recommendation since the recent waves of npm supply-chain attacks is to set ignore-scripts=true in ~/.npmrc and selectively allow trusted packages. pnpm and Bun ship close to this stance by default; npm and Yarn require opt-in.

If you are tracking down an ELIFECYCLE that disappears when you switch from npm to pnpm, the cause is almost always a transitive postinstall script that pnpm blocks and npm runs. Identify the package with npm install --verbose, then either fix it upstream or pin to a version without the offending script.

Stranger Causes I Have Tracked Down

Clear the npm cache

A corrupted npm cache can cause packages to install incorrectly, leading to ELIFECYCLE at runtime:

npm cache clean --force
rm -rf node_modules package-lock.json
npm install

Check for global and local version conflicts

If you have a package installed both globally and locally, the wrong version might run:

npm ls -g --depth=0

Compare with your local versions. If in doubt, remove the global install:

npm uninstall -g some-package

Run the failing script directly

Skip npm and run the command yourself to see unfiltered output:

# If your build script is "react-scripts build"
npx react-scripts build

This sometimes surfaces errors that npm’s logging truncates.

Check for antivirus or permissions interference

On Windows, antivirus software (especially Windows Defender) can lock files in node_modules during install, causing partial writes and subsequent ELIFECYCLE failures. Try adding your project directory to your antivirus exclusion list.

On Linux/macOS, permission issues can cause the same. If node_modules was created with sudo, you may not be able to modify it. Fix ownership:

sudo chown -R $(whoami) node_modules

Better yet, never use sudo with npm.

Use npm install --verbose

If you still can’t find the root cause, reinstall with verbose logging:

npm install --verbose 2>&1 | tee install-log.txt

The verbose output shows every HTTP request, file operation, and script execution. Search the log for the first error or warning.

Upgrade npm

Older versions of npm have bugs that cause spurious ELIFECYCLE errors. Update to the latest:

npm install -g npm@latest

Then clean install:

rm -rf node_modules package-lock.json
npm install

A prepare Script Runs in Production by Mistake

The prepare lifecycle runs on npm install in dev and when the package is published. A common foot-gun: a prepare script that calls husky install or runs tsc lands in your Docker build and fails because the dev tools were not installed. Set HUSKY=0 in production env, or move the script to prepare-only-for-dev and call it explicitly during local setup. Recent husky versions skip themselves when CI=true is set, which most CI providers do automatically.

Workspaces Hoist a Native Module to the Root

In npm/Yarn workspaces (and pnpm without strict hoisting), a native module like sharp or better-sqlite3 may be installed at the root node_modules, where it was compiled against the root’s Node version. If a workspace package then runs with a different Node binary (because of engines or a Docker stage), the prebuilt .node file fails to load with ELIFECYCLE. Run npm rebuild from the workspace directory, not the root, to force a fresh build against the workspace’s environment.

If your project lives on a network share, OneDrive, or a Windows shared folder, the symlinks npm creates inside node_modules/.bin may resolve incorrectly or be silently flattened to copies. The .bin shim then points at a path that no longer exists, and any script that uses a binary (webpack, tsc, vite) fails with ELIFECYCLE. Move the project to a local disk before debugging anything else; this is faster than fighting the network filesystem.

Try a different package manager

If npm keeps giving you problems, try pnpm or Yarn. They handle dependency resolution and script execution differently and sometimes avoid issues that npm hits:

npx pnpm install
pnpm run build

What Other Tutorials Get Wrong About ELIFECYCLE

Most npm tutorials list the same fixes but frame them in ways that produce subtle bugs.

They start with rm -rf node_modules. Reinstalling sometimes works, but you skipped reading the actual error. If the underlying script is broken (syntax error, missing module), reinstalling does nothing. Always read the error first; reinstall is fix 2, not fix 1.

They omit the errno meaning. Errno 1, 2, and 137 point to completely different root causes (generic, shell misuse, OOM). Articles that treat all ELIFECYCLE as the same fail to direct readers to the right fix.

They miss the difference between npm install and npm ci. ci is faster, deterministic, and designed for clean installs. Articles that recommend npm install --force or repeated rm -rf cycles miss that npm ci solves the same problem in less time.

They recommend --force and --legacy-peer-deps too quickly. Both flags suppress real warnings that signal upstream conflicts. Use them as a last resort, not as a default. Articles that show them as “just try this” train readers to hide problems instead of fixing them.

They confuse ELIFECYCLE with ERESOLVE. ELIFECYCLE is a script exit non-zero. ERESOLVE is a dependency tree conflict during install. They have different fixes; tutorials that group them under “npm error” miss the distinction.

They miss the supply-chain default difference between npm, pnpm, and Bun. pnpm 10 and Bun block transitive postinstall scripts by default; npm runs them. If a transitive postinstall is the culprit, switching package managers can resolve the ELIFECYCLE without any code change.

Frequently Asked Questions

Why is ELIFECYCLE not really an npm error?

Because npm only runs the script; it does not produce the error itself. The script exited non-zero, and npm wraps that exit with the ELIFECYCLE label. The actual error message is above the npm ERR! block in your terminal. Reading the error is always the first step.

What does errno 137 mean?

The kernel OOM-killer terminated the process. This happens when the Node process used more memory than the system or container allows. The fix is NODE_OPTIONS=--max-old-space-size=4096 (or higher), or to raise the container’s memory limit if running in Docker / Kubernetes.

Should I use npm ci or npm install?

npm ci for CI and clean reinstalls. It is faster, deterministic, and refuses to modify package-lock.json. npm install for adding or updating dependencies in development. If you are debugging ELIFECYCLE on a CI machine, switch to npm ci.

Is --force or --legacy-peer-deps safe to use?

Sometimes, but never as a habit. Both suppress warnings about real version conflicts. The right workflow is: try without the flag, read the conflict, decide whether the suppressed warning is benign or real. Pinning to a known-good version is almost always better than --force.

Why does my CI fail with ELIFECYCLE but local works?

Common reasons: different Node version (check engines in package.json), different Node memory limit (CI runners are tighter), different .npmrc (CI might lack secrets), and cache state differences. Reproduce locally with the same Node version and a clean node_modules before debugging CI specifically.

Should I switch to pnpm or Bun to avoid ELIFECYCLE?

Only if the cause is a transitive postinstall script that you cannot control. pnpm 10 and Bun block these by default; npm runs them. For other causes (your own scripts, native module compilation, OOM), switching managers does not help.

Related: If npm install fails due to dependency conflicts, see Fix: npm ERR! ERESOLVE unable to resolve dependency tree. If npm can’t find the script you’re trying to run, see Fix: npm ERR! Missing script: “start”.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles