ローカルではテストやインストールなどは問題なく進んでいたのに、いざ push すると CI がインストールステップで失敗するという現象が時折発生します。たとえばnpmでパッケージを管理しているアプリでは、以下のようなエラーが発生することがあります。
[chunk validate]: Running install: npm ci
npm error `npm ci` can only install packages when your package.json and
npm error package-lock.json ... are in sync.
npm error Missing: @emnapi/core@1.11.1 from lock file
npm error Missing: @emnapi/runtime@1.11.1 from lock file
本記事では、AI エージェントに実装を任せたセッションで、このような lock ファイルの不整合を push 前に検知する仕組みを紹介します。
CircleCI がリリースした Chunk を利用したローカルで CI 相当の検証を行うことにより、実行環境に依存するタイプの npm ライブラリを利用するプロジェクトで、push 後に CI がインストールステップで fail してしまう問題を解決します。
npm でネイティブ系パッケージのインストールに失敗するケース
WebAssembly ・ネイティブ系のライブラリをインストールしているか、依存関係に含めている場合、 npm install でライブラリをインストールすると、コマンドを実行した環境向けのパッケージのみがインストールされます。そのため、開発はmacOSでCIはLinux系のような異なる環境が開発サイクルの中に存在する場合、npm installした時と異なる環境では依存関係が見つからないというエラーが発生します。
この多くは、npm がプラットフォーム固有の optional 依存を package-lock.json に取りこぼす問題だとされています。
この現象は、通常のローカル開発では気づきにくいという厄介さがあります。ローカルで日常的に使う npm install はこの不整合を許容して進み、厳密に検査する npm ci は通常 CI でしか実行されないためです。つまり、push して CI が回るまで表面化しません。
npm install と npm ci の厳密さの違い
この不整合がローカルで表面化しないのは、日常的に使うコマンドが npm install だからです。両者の違いを次に示します。
| 観点 | npm install |
npm ci |
|---|---|---|
| lock との整合 | 差分があれば lock を更新して続行する | 差分があればその時点で失敗する |
| node_modules | 既存のものを再利用する | 削除して作り直す |
| 主な実行場所 | ローカルの開発中 | CI |
npm install は lock ファイルとのずれを許容して進むため、不整合があっても気づけません。一方、CI が実行する npm ci は lock ファイルを厳密な正とするため、そこで初めて失敗します。結果として、この不整合は push して CI が回るまで表面化しません。
Chunk Sidecar で Push 前の検証を必須化する
このような CI 環境でしか発生しない問題を発見するには、CIと同等の実行環境を利用した検証を実装時に行う必要があります。CircleCI が2026/07時点でプレビュー提供中の Chunk Sidecarは、この「ローカルあるいはコーディングエージェントが利用できる、CIと同等の実行環境を microVMで提供する仕組み」です。
Chunk CLIを事前にインストールし、chunk initコマンドを実行しましょう。リポジトリやパッケージマネージャ・テストコマンドなどを分析して、Claude Code向けのHookなどを設定します。
% chunk init
Detected package manager: npm
Detected command: test (npm test)
✓ Wrote .chunk/config.json
✓ Updated .gitignore with sidecar tracking patterns
✓ Wrote .claude/settings.json
Next step: scaffold .circleci/test-suites.yml for Smarter Testing
Ask your AI coding agent to scaffold .circleci/test-suites.yml — the
chunk-sidecar skill covers the file shape and per-language patterns.
Or rerun with --skip-test-suites=false to use built-in Go/pytest templates.
✓ Project initialized
簡単な nodejs アプリで chunk initとchunk skill installを実行すると、テストコマンドなどのタスクが.chunk/config.jsonに登録されます。
% cat .chunk/config.json
{
"commands": [
{
"name": "install",
"run": "npm ci",
"remote": true
},
{
"name": "test",
"run": "npm test",
"role": "gate",
"timeout": 300,
"limit": 3,
"remote": true
}
],
"vcs": {
"org": "hidetaka-cci",
"repo": "vitest-run-changed-test"
}
}
同時にClaude CodeのHookに、chunkコマンドを利用した検証が登録されます。
"Stop": [
{
"hooks": [
+ {
+ "type": "command",
+ "command": "chunk validate",
+ "timeout": 600
+ }
]
}
]
これによって、コーディングタスクがひと段落した(Stopした)タイミングにて、.chunk/config.jsonに定義された検証タスクが実行されます。
% chunk validate --list
install: npm ci
test: npm test
この仕組みによってnpm ciやnpm testコマンドが定期的に実行されるため、コーディングエージェントが push して CI を実行する前に問題を発見できます。
⏺ Ran 1 stop hook
⎿ Stop hook error: [chunk validate]:
Running install: npm ci
npm error code EUSAGE
npm error
npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm error npm error Missing: @emnapi/core@1.11.1 from lock file
Claude Codeが問題を検知したため、この後コマンドを実行してpackage-lock.jsonの更新が実行されます。
Ran 2 shell commands
package-lock.json を更新しました。テストは引き続き74件パスしています。
実際の作業では、package-lock.jsonの変更についてこの後報告があり、それを読んだことで著者がnpmにおける既知の Issue (npm/cli#4828)由来だと気づきました。そしてこの後問題を確実に回避するために、パッケージマネージャーを pnpmへ移行させています。
まとめ
パッケージマネージャーの仕様やライブラリの作りによっては、ローカルでは問題なく動くアプリが CI のインストールステップで失敗することがあります。
Chunk Sidecar のような CI 相当の検証をローカルで行う仕組みを取り入れることで、このような不整合を push 前に検出できます。本記事の事例では、ローカルで 74 件のテストがすべて通過したにもかかわらず、chunk の検証ゲートが実行した npm ci が lock ファイルの不整合を検出しました。AI エージェントによるコード生成は高速ですが、生成物がクリーンな環境でも成立するかは別の問題です。CI 相当の検証を inner loop に置くことで、この差を push 前に埋められます。
次のステップ
chunk を試す手順は次のとおりです。
- Chunk CLI をインストールする
- プロジェクトで
chunk initおよびchunk skill install
を実行し、スタックと検証コマンドを検出させる - AI エージェントから検証を inner loop で実行する
