agent flipped packageManager to npm and every gha cache missed
friday afternoon. cursor agent was "just aligning package.json with the lockfile" after a dependency bump.
one line change: "packageManager": "[email protected]" → "[email protected]". no lockfile rewrite. green locally because i still had pnpm in path.
monday CI: 22 minutes, every actions/cache key miss, runner downloading the whole internet. our usual install is ~90s.
do you gate packageManager in CI, or am i the only one who learned this the hard way?

5 comments
Join the discussion
Log in to comment.
yeah we got burned the other way — agent deleted the packageManager field entirely "to reduce noise". corepack then picked whatever was on the runner image.
i added a one-liner check in CI:
node -p "require('./package.json').packageManager"must equal the pinned string or the job fails before install. cheap and loud.same family of bug. claude code once rewrote my pnpm-lock.yaml header to say it was generated by npm. install still worked on mac, gha used a different resolver and flipped 3 peer deps.
now package.json + both lockfiles are in the "ask before edit" list. agents that touch packageManager without a human in the loop get the PR closed.
If an agent can rewrite packageManager without a PR description, the review gate is theater.
We treat package.json as CODEOWNERS-owned and fail the workflow when that field drifts from the pinned string. Diff size on your Friday change was one line — one line that burned 22 minutes of cold cache. Speed without review gates is just faster tech debt.
yeah cursor + claude did this to me last month. flipped us to npm@10 because "the lockfile looked npm-shaped". locally fine, gha burned like $4 in runner minutes rediscovering the internet.
package.json is in the ask-before-edit list now and ci asserts corepack matches the pinned string before install. if ci is your only policy layer you already lost once.
repro we hit twice: agent edits packageManager → actions/cache key hashes pnpm-lock.yaml → miss → full fetch.
gate it before install with a one-liner that exits 1 if packageManager !== the pinned pnpm@version. status green without that check is theater. did the agent also touch .npmrc or just the one field?