yarn install が CI で「The lockfile would have been modified」で失敗して通せない
The lockfile would have been modified は、手元で yarn install し、更新した yarn.lock をコミットすれば直る。
CI では immutable モードが既定で有効なためだ。
公開: 更新:
yarn install --immutable … ➤ YN0000: · Failed with errors in 0s 192ms
yarn install --immutable … ➤ YN0000: └ Completed ➤ YN0000: ┌ Link step ➤ YN0000: └ Completed ➤ YN0000: · Done in 0s 30ms
2026-10-16 に node:20(Yarn 4.5.0 / Node.js 20.20.2) で実際に打って取った出力。検証環境の詳細
要約
CI の yarn install が「YN0028: The lockfile would have been modified by this install, which is explicitly forbidden」で失敗するのは、yarn.lock が package.json の内容と同期していないことが原因である。
Yarn 2 以降は CI 上で lockfile の書き換えを禁止する immutable モードが既定で有効になるため、同期していない lockfile はエラーとして検出される。
手元で yarn install を実行して更新された yarn.lock をコミットすれば解決する。
実行例
package.json にだけ is-odd を足して yarn.lock を更新しないまま yarn install --immutable を実行すると、Post-resolution validation の段に追加されるはずの行が差分として並び、YN0028 で終了コード 1 になる。
解決策 1 のとおり yarn install で lockfile を更新したあとは、同じ --immutable が終了コード 0 で通る。
$ yarn install --immutable
➤ YN0000: · Yarn 4.5.0
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + is-odd@npm:3.0.1, is-number@npm:6.0.0
➤ YN0000: └ Completed
➤ YN0000: ┌ Post-resolution validation
➤ YN0000: │ @@ -8,12 +8,27 @@
➤ YN0000: │ "immutable-demo@workspace:.":
➤ YN0000: │ version: 0.0.0-use.local
➤ YN0000: │ resolution: "immutable-demo@workspace:."
➤ YN0000: │ dependencies:
➤ YN0028: │ + is-odd: "npm:3.0.1"
➤ YN0000: │ left-pad: "npm:1.3.0"
➤ YN0000: │ languageName: unknown
➤ YN0000: │ linkType: soft
➤ YN0000: │
➤ YN0028: │ +"is-number@npm:^6.0.0":
➤ YN0028: │ + version: 6.0.0
➤ YN0028: │ + resolution: "is-number@npm:6.0.0"
➤ YN0028: │ + languageName: node
➤ YN0028: │ + linkType: hard
➤ YN0028: │ +
➤ YN0028: │ +"is-odd@npm:3.0.1":
➤ YN0028: │ + version: 3.0.1
➤ YN0028: │ + resolution: "is-odd@npm:3.0.1"
➤ YN0028: │ + dependencies:
➤ YN0028: │ + is-number: "npm:^6.0.0"
➤ YN0028: │ + languageName: node
➤ YN0028: │ + linkType: hard
➤ YN0028: │ +
➤ YN0000: │ "left-pad@npm:1.3.0":
➤ YN0000: │ version: 1.3.0
➤ YN0000: │ resolution: "left-pad@npm:1.3.0"
➤ YN0000: │ checksum: 10c0/3fb59c76e281a2f5c810ad71dbbb8eba8b10c6cf94733dc7f27b8c516a5376cacea53543e76f6ae477d866c8954b27f1e15ca349424c2542474eb5bb1d2b6955
➤ YN0000: │
➤ YN0028: │ The lockfile would have been modified by this install, which is explicitly forbidden.
➤ YN0000: └ Completed
➤ YN0000: · Failed with errors in 0s 192ms
$ echo $?
1$ yarn install
➤ YN0000: · Yarn 4.5.0
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + is-odd@npm:3.0.1, is-number@npm:6.0.0
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0013: │ 2 packages were added to the project (+ 16.65 KiB).
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done in 0s 246ms
$ echo $?
0$ yarn install --immutable
➤ YN0000: · Yarn 4.5.0
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done in 0s 30ms
$ echo $?
0— 2026-10-16 時点の出力
検証環境Node.js 20.20.2 / npm 10.8.2 / Python 3.11.2 / 2026-10-16 検証(ほか 2 件)
- 検証日
- 実行環境
node:20Debian GNU/Linux 12 (bookworm)- バージョン
- Node.js 20.20.2
- npm 10.8.2
- Python 3.11.2
- Git 2.39.5
- Yarn 4.5.0
この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。
解決策
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 --versionpackage.json の packageManager フィールドに yarn --version で表示された版(例: yarn@4.0.0 の形式)を記載しておくと、Corepack が手元と CI で同じ Yarn を使うようになり、バージョン差による lockfile の揺れを防げる。
3. 一時的に immutable を無効化する(切り分け用)
YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn installCI 上でどんな差分が出るのかを確認したいときの切り分け手段である。
恒久設定にすると lockfile の同期ズレを検出できなくなるため、原因を特定したら必ず外す。
なお Yarn 1(classic)では --frozen-lockfile オプションが同種のガードで、エラーメッセージは違うが対処の考え方は同じである。
よくある原因
- lockfile のコミット漏れ:
package.jsonに依存を足したり版を上げたのに、更新後のyarn.lockをコミットしていない。 - Yarn バージョンの不一致: 手元と CI で Yarn の版が違うと lockfile の形式や解決結果が変わり、CI 側で「変更が必要」と判定される。
- immutable モード: CI と判定された環境では
enableImmutableInstallsが既定で有効になり、lockfile を変更するインストールが禁止される(公式のエラーコード一覧(新しいタブで開く)の YN0028)。 - workspace の反映漏れ: モノレポで一部の workspace だけ依存を変え、ルートの
yarn.lockへの反映が漏れている。