Skip to content
Latchkey

npm ENOENT package.json Not Found in CI - Fix Missing Manifest

ENOENT for package.json means npm looked for the manifest in the current directory and there was no file there. It is almost always a working-directory or checkout problem.

What this error means

An install or run step fails right away with code ENOENT and a path ending in package.json, saying npm could not read the file. Running locally from the project root works fine.

npm
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /home/runner/work/repo/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '.../package.json'

Diagnose it: reproduce the CI install locally

Install failures are usually environment drift rather than a broken lockfile: a different package-manager major, a different Node version, or a cache that is being restored from a run with different inputs. Reproduce the CI conditions before changing the lockfile, because regenerating it hides the real cause.

Terminal
# match the runner exactly, then install from a clean slate
node --version && npm --version
rm -rf node_modules
npm ci --foreground-scripts

# if that succeeds locally but fails in CI, the difference is the cache
# or the package-manager version, not your lockfile

Common causes

The job runs npm from the wrong directory

The package.json lives in a subfolder, but the step runs at the repo root (or vice versa), so npm finds no manifest.

The checkout did not include the manifest

A missing or shallow checkout, or a sparse-checkout that excluded the project folder, leaves no package.json on disk.

How to fix it

Run npm in the directory that contains package.json

  1. Confirm where package.json lives in the repo.
  2. Set the working directory for the install step to that folder.
Workflow
- name: Install
  working-directory: ./app
  run: npm ci

Ensure the repo is checked out first

  1. Add the checkout step before any npm step.
  2. Verify the path with ls so the manifest is present.
Workflow
- uses: actions/checkout@v4
- run: ls package.json && npm ci

Verify the fix survives a cold cache

A green run immediately after a fix often proves nothing, because it restored a cache written before the change. Force a cold install once to confirm the fix is real.

.github/workflows/ci.yml
# temporarily bust the cache key to prove the fix on a cold runner
- uses: actions/setup-node@v4
  with:
    node-version: 22
    cache: npm
    cache-dependency-path: package-lock.json
# then bump this suffix once, run, and remove it
#   key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}-v2

How to prevent it

  • Always run actions/checkout before npm, set working-directory explicitly for subfolder projects, and add a quick ls of package.json to fail fast with a clear message.

Frequently asked questions

What causes npm ENOENT package.json not found in CI?
There are 2 common causes: the job runs npm from the wrong directory and the checkout did not include the manifest. The package.json lives in a subfolder, but the step runs at the repo root (or vice versa), so npm finds no manifest.
How do I fix npm ENOENT package.json not found in CI?
There are 2 fixes depending on which cause you have: run npm in the directory that contains package.json and ensure the repo is checked out first. Work through them in order, since the first is the most common.
What does npm ENOENT package.json not found in CI actually mean?
An install or run step fails right away with code ENOENT and a path ending in package.json, saying npm could not read the file.
How do I stop npm ENOENT package.json not found in CI happening again?
Always run actions/checkout before npm, set working-directory explicitly for subfolder projects, and add a quick ls of package.json to fail fast with a clear message.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card