pnpm frozen lockfile 錯誤怎麼修?先對齊 lockfile 與版本
ERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE 的意思不是「lockfile 一定壞了」,而是 pnpm 在不可改寫 lockfile 的模式下,判定目前的 package.json、package manager 設定或解析輸入,和 pnpm-lock.yaml 的記錄對不起來。
先不要刪除 lockfile,也不要在 CI 直接改成沒有 --frozen-lockfile 的安裝。正確做法是先辨認錯誤屬於 manifest 漂移、pnpm 版本 pin 需要重新解析、devEngines.packageManager 設定,還是舊版相容性資料庫造成的額外依賴。pnpm 11.24.0 已修正其中一個 pinned pnpm 的 frozen install 路徑;pnpm 12.0.0-rc.10 另修正 build metadata 與 TypeScript 7 相容性案例,但 RC 仍不適合直接當 production 預設版本。
先收集四項輸入
在修改任何檔案前,先記下執行環境與版本。這些輸出可以讓 reviewer 分辨「同一份 lockfile 在不同 pnpm 版本執行」和「manifest 真的變了」:
pnpm --versionnode --versiongit status --shortrg -n 'packageManager|devEngines|lockfileVersion|packageManagerDependencies|settings:' \ package.json pnpm-workspace.yaml pnpm-lock.yaml接著確認目前的 CI 命令是否真的是 frozen install:
pnpm install --frozen-lockfile如果這一步失敗,先保留完整錯誤訊息與 pnpm 版本。不要先執行會改寫 lockfile 的一般 pnpm install,否則真正的輸入差異可能被新的 lockfile diff 蓋掉。
四種常見原因
| 症狀 | 先檢查什麼 | 正確方向 |
|---|---|---|
package.json 新增或移除依賴 | manifest 與 importer 區塊 | 在分支中刻意執行一般 install,review manifest 和 lockfile 一起提交 |
| lockfile 記錄了需要重新解析的 pnpm pin | packageManager、devEngines.packageManager 與 lockfile 的 packageManagerDependencies | 使用專案指定的 pnpm 版本,再重跑 frozen install |
devEngines.packageManager 使用 +algorithm.hash 等 build metadata | package manager pin 和錯誤訊息 | 使用包含修正的 pnpm 版本,確認 lockfile 是否保持不變 |
舊版相容性資料庫替 @typescript-eslint/types 帶入 TypeScript 7 | @typescript-eslint 版本與 Cannot read properties of undefined (reading 'Intrinsic') | 先用穩定版驗證,或在隔離矩陣測試 pnpm 12 RC 10 |
這四類都可能顯示相似的 frozen lockfile 錯誤,但修復方式不同。尤其是「一般 install 會顯示 Already up to date,frozen install 卻失敗」的案例,不代表 CI 不需要 lockfile;它可能只是 pnpm 沒把 pinned manager version 寫入 lockfile。
修復順序:先對齊,再決定是否重寫
1. 使用 lockfile 指定的 pnpm
先看 package.json 是否有 packageManager 或 devEngines.packageManager。CI 應使用專案已提交的版本管理流程,不要讓每個 runner 透過未固定的 latest 自動取得不同 pnpm。重新執行後再次確認:
pnpm --versionpnpm install --frozen-lockfile如果 exact pnpm version 對齊後就通過,問題是執行器版本不一致;把版本 pin 和安裝方式補進 CI 文件,避免只在個人電腦修好。
2. 如果是刻意變更依賴,才使用一般 install
當 package.json 的依賴確實改了,frozen install 失敗是應有的保護。請在獨立分支或 pull request 中執行一般安裝,然後同時審查三份輸入:
pnpm installgit diff -- package.json pnpm-workspace.yaml pnpm-lock.yaml只接受與需求相符的 importer、版本與 integrity 變更。完成 review 後,CI 回到:
pnpm install --frozen-lockfile不要為了讓 CI 綠燈而刪除 pnpm-lock.yaml;那會把依賴更新和錯誤排查混成一次不可控的重解析。
3. 使用 pnpm 11.24.0 修正 pinned manager 路徑
pnpm 11.24.0 的 release note 指出:當 lockfile 已記錄的 pnpm 版本需要先重新解析才能安裝時,pnpm install --frozen-lockfile 不再因此回報 ERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE;它會執行 lockfile pin 的 pnpm,並保持 lockfile 不變。
這個修正適合已在 pnpm 11 stable 路線的專案。升級 pnpm 本身也要當成有審查的變更,先在一個 runner 或矩陣 job 驗證,再更新專案 pin;不要把「工具修正」和「依賴升級」塞進同一個無法回溯的提交。
4. 只有特定案例才測試 pnpm 12 RC 10
pnpm 12.0.0-rc.10 的 release note 另外修正:
devEngines.packageManager的+<algorithm>.<hash>build metadata 不應讓 frozen install 失敗。- lockfile 需要重新解析 pinned pnpm 時,應使用已 pin 的版本且不改寫 lockfile。
- 相容性資料庫不再只因靜態分析結果,就替發布套件加入只在型別匯入的依賴;官方特別列出
@typescript-eslint/types可能意外拉到 TypeScript 7,導致舊版 ESLint 出現Intrinsic錯誤。
RC 是測試訊號,不是穩定版承諾。若 production 仍使用 pnpm 11,先以 11.24.0 修正後的 stable 路徑為主;若要評估 pnpm 12,請在獨立 workspace 與 CI matrix 固定 Node、registry、pnpm 和 lockfile,並保留快速回退的 pin。
驗證「沒有偷偷改 lockfile」
處理完版本或設定後,除了 frozen install,還要確認工作樹沒有非預期的 lockfile 變更:
pnpm install --frozen-lockfilegit diff --exit-code -- pnpm-lock.yaml如果要重建 lockfile,請先在分支中明確記錄原因,再用一般 install 產生 diff;驗證完後切回乾淨 checkout 跑 frozen install。對 workspace 專案,也要檢查 pnpm-workspace.yaml 的 catalog、package glob 和 importer 是否與提交內容一致。
若錯誤仍然只發生在某個 CI runner,將 Node、pnpm、registry、環境變數與 cache 狀態列入比較,不要立刻把 cache 清除當成修復。cache 可以影響重現速度,但不應成為依賴圖正確性的唯一來源。
本篇處理的是錯誤碼本身;若你要評估 pnpm 12 RC 的 cycle、workspace 排序和 candidate upgrade,可以接著看 pnpm 12 RC 10 lockfile 與相容性驗證。兩篇文章的搜尋意圖不同:這篇先讓 CI 恢復可解釋的 frozen install,那篇才討論 RC 是否值得進入測試矩陣。
常見問題
Q: 可以直接刪掉 pnpm-lock.yaml 再重裝嗎?
A: 不建議。刪除 lockfile 會同時移除原本可重現的解析輸入,讓你無法判斷原錯誤是 manifest 漂移、pnpm pin,還是工具版本 bug。只有在團隊明確決定重新解析依賴,並且已審查完整 diff 時,才應建立新的 lockfile。
Q: pnpm install 通過,但 pnpm install --frozen-lockfile 失敗,哪個才是對的?
A: 兩者用途不同。一般 install 可以更新 lockfile,frozen install 會拒絕改寫;CI 應以 frozen install 驗證提交內容是否可重現。先比較兩次命令是否改變 lockfile,再處理真正的輸入差異。
Q: production 應該直接升到 pnpm 12 RC 10 嗎?
A: 不應只因為這個錯誤就直接切換 RC。先使用目前 stable major 的修正版,例如 pnpm 11.24.0;只有在需要 RC 10 特定修正或要提前驗證 pnpm 12 時,才在隔離矩陣中測試並保留回退 pin。
參考資料:
回報錯字、失效連結,或告訴我你想看的延伸主題。