できない.dev

yarn install が CI で「The lockfile would have been modified」で失敗して通せない

CI の yarn install が YN0028 で止まるのは、yarn.lock の内容が package.json と同期していないことが原因。
手元で yarn install を実行し、更新された yarn.lock をコミットすれば解決する。

公開:

要約

CI の yarn install が「YN0028: The lockfile would have been modified by this install, which is explicitly forbidden」で失敗するのは、yarn.lockpackage.json の内容と同期していないことが原因である。

Yarn 2 以降は CI 上で lockfile の書き換えを禁止する immutable モードが既定で有効になるため、同期していない lockfile はエラーとして検出される。
手元で yarn install を実行して更新された yarn.lock をコミットすれば解決する。

よくある原因

  1. lockfile のコミット漏れ: package.json に依存を足したり版を上げたのに、更新後の yarn.lock をコミットしていない。
  2. Yarn バージョンの不一致: 手元と CI で Yarn の版が違うと lockfile の形式や解決結果が変わり、CI 側で「変更が必要」と判定される。
  3. immutable モード: CI と判定された環境では enableImmutableInstalls が既定で有効になり、lockfile を変更するインストールが禁止される(公式のエラーコード一覧(新しいタブで開く)の YN0028)。
  4. workspace の反映漏れ: モノレポで一部の workspace だけ依存を変え、ルートの yarn.lock への反映が漏れている。

解決策

1. 手元で lockfile を更新してコミットする

yarn install
git add yarn.lock
git commit -m "chore: update yarn.lock"
git push

これが本筋の対処で、CI ではこのエラーは「lockfile を直してから来い」という合図である。

2. Yarn のバージョンを手元と CI で揃える

corepack enable
yarn --version

package.jsonpackageManager フィールドに yarn --version で表示された版(例: yarn@4.0.0 の形式)を記載しておくと、Corepack が手元と CI で同じ Yarn を使うようになり、バージョン差による lockfile の揺れを防げる。

3. 一時的に immutable を無効化する(切り分け用)

YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install

CI 上でどんな差分が出るのかを確認したいときの切り分け手段である。
恒久設定にすると lockfile の同期ズレを検出できなくなるため、原因を特定したら必ず外す。

なお Yarn 1(classic)では --frozen-lockfile オプションが同種のガードで、エラーメッセージは違うが対処の考え方は同じである。

この記事は役立ちましたか?