Skip to content

npm ci can fail on a fresh install due to unpinned peer/transitive ranges drifting (picomatch, yaml) #321

Description

@Bryandero98

Summary

While investigating the failing Netlify deploy previews on #246 and other recent PRs, I found that a completely fresh npm ci (matching what CI/Netlify does) currently fails against the committed package-lock.json on main - independent of any code change in a given PR.

Reproduction

# Node 20.18.1 / npm 10.8.2 (matches .nvmrc / engines)
rm -rf node_modules
npm ci

Result:

npm error `npm ci` can only install packages when your package.json and package-lock.json ... are in sync.
npm error Invalid: lock file's picomatch@2.3.2 does not satisfy picomatch@4.0.7
npm error Missing: picomatch@2.3.2 from lock file
npm error Invalid: lock file's yaml@1.10.3 does not satisfy yaml@2.9.0
npm error Missing: yaml@1.10.3 from lock file

Root cause

fdir@6.5.0 (pulled in via vite) declares an optional peer dependency on picomatch@"^3 || ^4", and vite@8.1.0 depends on yaml@"^2.4.2". The lock file currently only pins picomatch@2.3.2 at the root (for micromatch@"^2.3.1") and yaml@1.10.3 at the root (for cosmiconfig@"^1.10.0"), with nested picomatch@4.0.4 overrides for vite/vitest/tinyglobby specifically - but nothing satisfying fdir's peer range or vite's yaml range. Since these are floating (^) ranges, a resolver doing a truly fresh resolution today can compute a different (newer) target version than whatever was resolved when the lock file was last regenerated, and npm ci's stricter consistency check then rejects the lock file outright.

Why I'm not opening a PR for this directly

I attempted to regenerate package-lock.json (rm -rf node_modules && npm install) to fix this, but doing so from a Windows machine collapses the lock file's cross-platform optionalDependencies entries for lightningcss (currently 11 platform variants: linux/darwin/win32 x arm/x64/musl/gnu) down to just the Windows one - which would break installs on Linux/macOS CI. A safe fix needs to be regenerated on a Linux environment matching your actual build image (or produced with an npm version/flow that preserves all platform variants), which I can't fully verify from here. I didn't want to hand you a lock file I couldn't be fully confident in.

I also wasn't able to pull the actual Netlify build log for the failing deploy previews (e.g. https://app.netlify.com/projects/smart-drop/deploys/6a8dff377ca3dc00098390ef) without an authenticated Netlify session, so I can't 100% confirm this is the exact failure Netlify hits versus something else - but the npm ci failure above is real, reproducible today on a clean main checkout, and would affect any CI step that uses npm ci (which is the standard, recommended install command for CI, unlike npm install).

Suggested fix (for whoever picks this up with the right environment)

On a Linux box (or your CI image) with Node 20.x / matching npm:

rm -rf node_modules package-lock.json
npm install

then verify npm ci succeeds cleanly on a second fresh checkout, and diff the resulting lock file against the current one to confirm the lightningcss platform variants are still all present before committing.

Happy to help verify further if useful - just didn't want to guess on the platform-specific parts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions