CIでpnpm installがERR_PNPM_OUTDATED_LOCKFILEやlockfile不一致を示して停止したら、最初にfrozen installを無効化して通すのではなく、どのworkspaceのmanifestとpnpm-lock.yamlがずれているかを特定します。pnpm公式CLI docsは、CIではlockfileが更新を必要とするとinstallが失敗し、--frozen-lockfileではmanifestとlockfileが同期していない場合にlockfileを生成せずinstallationが失敗すると説明しています。ただし、error codeや文章はpnpmの版や失敗箇所で違うことがあります。codeだけで根本原因を断定せず、実際のエラー全文、pnpm version、作業directory、workspace設定を残してください。
この記事では、package manifestの依存変更、workspace importerの更新漏れ、pnpm version/設定差、間違ったrootでのinstall、merge conflictを順に切り分けます。意図されたdependency変更ならmanifestとlockfileを同じ変更としてレビューし、意図しないversion更新は避けます。原因が分からない間はCIで--no-frozen-lockfileを使って合格にせず、lockfileの差分を確認するまで止めるのが基本です。
目次
先に環境とコマンドを固定する
失敗したCIとローカルで、以下を同じ記録表へ書き出します。対象commit SHA、実行directory、pnpmのversion、Node.js version、実際のinstall command、CIを示す環境変数、rootのpackage.json、対象workspaceのpackage.json、pnpm-workspace.yaml、pnpm-lock.yamlの変更状況です。pnpmはworkspace root内の全projectをinstall対象とする設定が既定の場合があり、package内のサブディレクトリだけでコマンドを実行していると、別の設定・lockfileを見ている可能性があります。まずpwdとworkspace rootを照合します。
次にlockfileがどこにあるかを確認します。通常のworkspaceでは共有lockfileがrootに置かれる構成がありますが、repository設定によっては異なる場合もあります。rootのpnpm-workspace.yamlがあるか、packageのworkspace selectorがどのprojectを含むか、CIがそのrootをcheckoutしているかを見ます。ファイルが存在しない場合、同期エラーとは別の分岐になります。manifestがmonorepoの一部だけ更新されたのか、workflowが誤ったsubdirectoryでinstallしているのかを、ログと設定から分けます。
ログにはtoken、private registryのcredential、署名付きURLを含めず、pnpm versionとerror messageの必要部分だけを共有します。pnpm config listや.npmrc全体の出力をそのままissueへ貼らないでください。registry設定が必要なら、機密情報を除いて必要な設定名と安全な値だけを記録し、権限のある担当者がprivate package accessを確認できる形にします。
importerとspecifierの差分を特定する
pnpm-lock.yamlを開き、エラーに出たworkspace packageのimporterを探します。lockfileのimporterには、そのprojectの依存specificationや解決情報が記録されます。対応するpackage.jsonのdependencies、devDependencies、optionalDependencies、peerDependencies、workspace package参照と照合し、追加・削除・version rangeの変更がlock側に反映されているかを見ます。エラーが特定のimporterを示す場合は、lock全体を再生成する前にその項目を確認してください。
manifestに依存追加・削除・range変更があり、lockfileに対応差分がない場合は、変更漏れが候補です。両方に差分がある場合も、specifierが同期しているか、resolved versionが意図に沿っているか、更新された範囲が必要なdependencyに限られているかをレビューします。lockfileだけが変わった場合は、別pnpm版で再生成した、workspace設定を変更した、別branchのlockを取り込んだ、merge conflictを誤解決した可能性を調べます。変更の意図と各lock diffが説明できる状態まで、広いlockfile差分を承認しません。
monorepoでは複数importerの同時変化があります。新たなworkspace package、workspace: protocol、file:依存、peer dependency、optional dependencyなどの差が、root importerと対象packageの双方にどう記録されるかを確認します。pnpm-workspace.yamlのpackages patternを変えた場合は、対象projectがworkspaceに含まれたり外れたりしていないかをチェックします。pnpm公式docsではworkspaceのroot配置や、workspace: protocolが指定されたversion範囲と一致するworkspace packageだけを参照する性質が説明されています。これらの設定を見ずに「lockfileを最新化すればよい」と決めないでください。
frozen installがCIだけで失敗する場合
pnpm公式CLI docsでは、CI環境でlockfileが更新を必要とするとinstallが失敗すること、--frozen-lockfileはCIでlockfileがある場合に既定でtrueになることが説明されています。そのため、ローカルでpnpm installが完了したのにCIのfrozen installだけが止まる場合、ローカルはlockfileを更新し、CIは更新しない状態で検査している可能性があります。ローカルのinstall前後でlockfileが変わったかを確認し、CIと同じpnpm版・同じroot・同じ設定で試します。ローカルで単に成功したという事実は、committed lockfileが同期済みである証拠にはなりません。
pnpmのversion差がある場合、lockfileの構造・生成挙動・workspace処理がどの版に対応しているかを確認します。.npmrcやpnpm-workspace.yamlにはlockfile生成に影響する設定があり得るため、CIとlockを生成した環境で共有設定を比べます。特定versionの既知bugを疑う場合は、issueやrelease noteが実際のpnpm版、error message、workspace条件に当てはまるかを照合します。過去のissueが似た文字列を持つだけでは現在の原因を証明しません。必ず使われたpnpm versionを記録します。
package manager versionをpackageManager欄、Corepack設定、CI action、setup scriptなどのどこで管理しているか確認します。単に新しいpnpmへ上げる、あるいはローカル版をCIへ合わせるだけでは、lockfileが意図通りかの答えにはなりません。チームで使う版を変更する場合は、それ自体が独立した変更として理由を説明し、lockfileの差分を再確認します。今回のエラーを解消するためにpackage managerのversion pinを変える必要があるかは、現状のrepository contractを見て判断してください。
安全なlockfile更新の進め方
依存変更が意図的で、対応するlockfile差分が不足していると確認できたら、作業前のmanifest・lockfile・workspace設定の差分を保存し、専用branchまたは隔離worktreeで更新します。projectが指定するpnpm版とworkspace rootを使い、lockfileを再生成して差分をレビューします。pnpm install --no-frozen-lockfileはlockfile更新を許すための選択肢ですが、CIでエラーを隠すために恒久追加するのではなく、管理された更新作業の中で使用します。更新後はfrozen installに戻して検証し、commitするlockfileがCIの検査対象になっていることを確かめます。
pnpm install --lockfile-onlyはnode_modulesを書き換えない更新方法として記載されていますが、manifestやlockfileに関する変更が起き得るため、「副作用が一切ない」とは扱いません。実行前にversionと設定を揃え、実行後にpnpm-lock.yamlだけでなくpackage.jsonやworkspace設定を含めた差分を確認します。現行pnpm docsでは--dry-runが依存解決を行い、書き込みなしに実installの変更候補を報告するoptionとして案内されていますが、比較的新しい版で追加された機能です。対象プロジェクトのpnpm versionが対応しているかを確認し、dry-runで更新候補が出てもfrozen installの検証が通ったことにはしません。
lockfileを手編集したり、削除してからinstallし直したりするのは最後の手段ではなく、通常は避けるべき方法です。lockをゼロから再生成すると、意図したmanifest変更と無関係なresolved dependencyの更新や広範なdiffが発生し得ます。pnpmの--forceも単なるlock mismatch解消スイッチではなく、lockfileやmodules directoryの互換性に関わる再生成等を行うoptionです。原因が不明なまま使わず、差分の必要性と影響範囲を説明できる場合だけ、管理された復旧手順を採用します。
workspace・設定の確認表
rootのpnpm-workspace.yamlで指定されたpackages patternと、実際のpackage directoryを照合します。エラーのimporterがlockfileにない場合は、新規workspace packageの追加漏れ、pattern不一致、rootの取り違えを確認します。packageはあるのにspecifierがずれている場合は、そのmanifestの依存定義、protocol、version range、lockfile上の同じimporterを対にして見ます。workspace:参照なら、要求versionがworkspace内のpackageと一致するかを調べ、file/local dependencyならCI checkoutにも参照先が存在するかを確認します。
.npmrc、pnpm-workspace.yaml、CorepackやCI setup step、shell commandを比較するときは、secretを含む値を除きます。pnpm version、workspace root、frozen setting、lockfile生成時の公開可能な設定を表へまとめます。CIで別のlockfile pathを指定している、frozen optionがworkflow commandに明示されている、あるいはenvironmentの判定で既定動作が変わる場合は、その差を記録します。設定を変更する前に、エラーが要求する条件と関係する設定だけに範囲を絞ります。
修復後の検証
更新後は、まずmanifestとlockfileのdiffが意図した依存変更を表すことをレビューします。無関係なversion更新、workspace importerの消失、peer dependencyの別解決、lockfile formatの大幅な変更が入っていないかを見ます。package.jsonやpnpm-workspace.yamlも変更されている場合、lock再生成に必要な変更なのか、別の作業が混ざったのかを説明できなければ分離します。pnpmの更新自体をlockfile差分の説明として済ませないでください。
その後、clean checkoutまたは隔離されたCI jobで、同じcommit、同じpnpm version、同じworkspace root、同じ環境条件を使ってpnpm install --frozen-lockfileを実行します。終わったらpackage manifests、pnpm-lock.yaml、workspace設定に意図しない変更がないことを確認し、プロジェクトの通常testsとbuildも実行します。ローカルの成功だけでCIまで直ったと判断せず、対象CI workflowで同じfrozen installを確認します。実際にCIを実行していない場合は、「ローカルで検証済み」「CI未実行」を分けて記録します。
CIが成功しない場合、失敗の種類を区別します。outdated lockfileのままならmanifest・workspace・設定の照合に戻ります。registry認証・network errorはlockfile整合性と別の問題です。tarball integrityやpackage resolution errorも、lockfile同期エラーとしてまとめず、pnpmが表示する正確なcodeとpackageを記録して対応する公式手順を探します。問題が残るときは、変更前後のmanifest/lock差分、pnpm/Node版、CI command、エラー全文のsecret redacted copyを揃えて担当者へ渡します。
やってはいけない回避
・CIに--no-frozen-lockfileを常時追加し、manifest/lock mismatchを見えなくする。
・error codeだけを見て、対象importerやworkspace rootを確認せずlock全体を再生成する。
・原因不明のままpnpmを最新化し、大量のlockfile変更を一度に取り込む。
・pnpm-lock.yamlを削除し、どの依存が変わるかを確認せず再生成する。
・lockfileのspecifierやintegrity値を手作業で編集する。
・CIのprivate registry credentialsをログやissueへ貼る。
・--dry-runが0終了したことだけでfrozen installがPASSしたと報告する。
このエラーへの実務的な判断は、依存変更をしたかどうかから始めます。意図した変更なら、対応するlockfileが同じbranchで更新され、CIがその内容を検証できるようにします。依存変更をしていないのにoutdatedとなるなら、workspaceの場所、manifest差分、pnpm version、共有設定、merge経緯を調べます。--no-frozen-lockfileは原因を解消するのではなく、更新を許可するだけです。更新後にcleanなfrozen installを通すところまでを復旧の完了条件にし、実行していないテストを成功扱いしません。
まとめ:最短の切り分け順
-
完全なerror、pnpm/Node版、commit、実行path、commandを記録する。
-
workspace root、
pnpm-workspace.yaml、root lockfileの場所を確認する。 -
エラーに示されたimporterとmanifestの依存specifiersを照合する。
-
dependency change、merge conflict、pnpm version・設定差のどれかを特定する。
-
意図した変更だけlockfileへ反映し、manifest・workspace・lock diffをレビューする。
-
clean環境で同じ条件の
pnpm install --frozen-lockfileを再実行する。 -
CI workflowでも再検証し、実行した環境と未実行範囲を記録する。
必要な情報を揃えてもlock差分が説明できない場合は、更新を急がず、変更を分離して元の状態から差分を作り直します。エラーがoutdated lockfileではなく認証、network、tarball integrity、dependency resolutionを指しているなら、それぞれの原因に分岐し、この手順を当てはめません。本文で特定版のバグや常に発生する原因を断定せず、現行の公式CLI contractと、対象projectで実測した環境の結果を区別することが、再現可能な修復につながります。
参考資料
確認日:2026-10-15。pnpm公式Install / Workspaces docsを確認。記載は一般的な診断手順であり、特定repositoryのlockfile、pnpm version、CIを実行検証した結果ではありません。
pnpm install: https://pnpm.io/cli/install(新しいタブで開く)
pnpm Workspaces: https://pnpm.io/workspaces(新しいタブで開く)
