The current build workflows use node-version: lts/krypton as a floating alias in all actions/setup-node steps.
This alias resolves to whichever specific Node.js point-release GitHub distributes at the time the job runs. When that underlying version changes (e.g., a Node.js patch bump ships a newer bundled npm), npm ci --prefer-offline --no-audit --include=optional can fail because:
-
Lockfile version mismatch — package-lock.json is committed with a lockfileVersion generated by a specific npm major/minor (e.g., npm 11.x.y). If the runner resolves lts/krypton to a Node release bundled with a different npm, npm ci exits with an error like:
npm error npm ci can only install packages when your package.json and package-lock.json are in sync.
or (with newer npm):
npm warn old lockfile The package-lock.json file was created with an older version of npm...
-
--prefer-offline amplifies the failure — this flag instructs npm to use the local cache as much as possible and avoid network requests. On a cache miss (which is almost guaranteed after a Node version bump because the cache key is tied to the OS + Node version + lock file hash), npm cannot fall back to the registry and the install fails outright instead of degrading gracefully.
-
engines field mismatch between CI and local — package.json declares "node": "^24.0.0" and "npm": "11" in the engines field, yet lts/krypton resolves to Node.js 22.x in CI. This means CI is running a version that would be rejected by npm install locally, and any engines-strict tooling or postinstall scripts will emit warnings or errors.
Recommenation
- Pin an explicit Node.js version aligned with engines e.g.
node-version: '24.0.0'
- Remove or replace --prefer-offline
--prefer-offline is appropriate only when a warm local cache is guaranteed. In CI the cache is keyed on package-lock.json hash and OS; any change invalidates it. Replacing it with --prefer-frozen-lockfile equivalent (npm ci already implies this) or simply omitting the flag is safer: run: npm ci --no-audit --include=optional
If install speed is a concern, rely on the cache: 'npm' parameter in actions/setup-node (which sets up ~/.npm caching correctly) and let npm fall back to the registry on a miss.
The current build workflows use
node-version: lts/kryptonas a floating alias in all actions/setup-node steps.This alias resolves to whichever specific Node.js point-release GitHub distributes at the time the job runs. When that underlying version changes (e.g., a Node.js patch bump ships a newer bundled npm),
npm ci --prefer-offline --no-audit --include=optionalcan fail because:Lockfile version mismatch — package-lock.json is committed with a lockfileVersion generated by a specific npm major/minor (e.g., npm 11.x.y). If the runner resolves lts/krypton to a Node release bundled with a different npm, npm ci exits with an error like:
npm error
npm cican only install packages when your package.json and package-lock.json are in sync.or (with newer npm):
npm warn old lockfile The package-lock.json file was created with an older version of npm...
--prefer-offline amplifies the failure — this flag instructs npm to use the local cache as much as possible and avoid network requests. On a cache miss (which is almost guaranteed after a Node version bump because the cache key is tied to the OS + Node version + lock file hash), npm cannot fall back to the registry and the install fails outright instead of degrading gracefully.
engines field mismatch between CI and local — package.json declares "node": "^24.0.0" and "npm": "11" in the engines field, yet lts/krypton resolves to Node.js 22.x in CI. This means CI is running a version that would be rejected by npm install locally, and any engines-strict tooling or postinstall scripts will emit warnings or errors.
Recommenation
node-version: '24.0.0'--prefer-offlineis appropriate only when a warm local cache is guaranteed. In CI the cache is keyed onpackage-lock.jsonhash and OS; any change invalidates it. Replacing it with--prefer-frozen-lockfileequivalent (npm ci already implies this) or simply omitting the flag is safer:run: npm ci --no-audit --include=optionalIf install speed is a concern, rely on the cache: 'npm' parameter in actions/setup-node (which sets up ~/.npm caching correctly) and let npm fall back to the registry on a miss.