claude plugin evalがgit 2.30で止まる原因 — 2.31未満を拒否する理由
git 2.30 is too oldと出てexit 1で止まる原因と直し方。GIT_CONFIG_COUNTがgit 2.31からの機能であること、v2.1.283より前の挙動、直し方とCIでの切り分けまで。
claude plugin eval が git 2.30 is too old for claude plugin eval と表示して、ケースを1つも走らせずに終了する場合があります。原因はPATH上のgitが2.31より古いことです。gitを2.31以降に入れ替えて、同じコマンドを再実行すれば進みます。
止まるのはバグではなく意図した動作です。evalの各runは、リポジトリのgit設定が起動できるプログラムを無効にした状態で走らせる設計で、その無効化を古いgitが無視してしまうためです。この記事では、メッセージの意味、止める理由、直し方、CIでexit 1が出たときの切り分けを順に書きます。
表示されるエラーと終了コード
出力は次の1行です。バージョン部分は手元のgitに応じて変わります。
git 2.30 is too old for claude plugin eval: it ignores the environment configuration (GIT_CONFIG_COUNT, added in git 2.31) that switches off the repository's git hooks and helper programs for the run. Install git 2.31 or newer.claude plugin eval はこのメッセージを出し、caseを1つも走らせないまま終了コード1で終わります。caseを走らせる前の停止なので、caseごとのスコアは1件も出ません。
要件のページでは、gitの条件は「gitが入っているなら2.31以降」と書かれています。Claude Code本体はv2.1.269以降が必要で、gitの条件はそれとは別枠です。
このエラーの前提
- 対象: PATH上の
gitが2.31未満のとき - 結果: ケースを実行せずexit 1
- 対象外: gitがそもそも入っていない環境(通常どおり実行される)
なぜ2.31未満だと止めるのか
evalの各runでは、Claude Codeがgitのhook、資格情報ヘルパー(credential helper)、そのほか「リポジトリのgit設定が起動できるプログラム」を無効にします。無効化には環境変数による設定注入が使われ、GIT_CONFIG_COUNT がその入口です。
この環境変数はgit 2.31で入った仕組みです。gitのドキュメントでは、GIT_CONFIG_COUNT が正の数なら、GIT_CONFIG_KEY_<n> と GIT_CONFIG_VALUE_<n> の組がその個数だけ実行時の設定に加わると説明されています。設定ファイルの値は上書きされ、git -c の明示指定には負けます。
2.30以前のgitはこの変数を読みません。つまり無効化の指示が黙って無視され、hookや資格情報ヘルパーが生きたままrunが走ります。そうなると、採点対象のrunの中で任意のプログラムが実行されるおそれがあるので、claude plugin eval は実行自体を拒否します。
環境変数でhookが切れる様子
仕組みは手元でも確かめられます。次の例は、pre-commit hookを置いたリポジトリで、通常のコミットと core.hooksPath を環境変数で差し替えたコミットを比べたものです(git 2.50.1で実行)。
git init -q r && cd r
printf '#!/bin/sh\necho "pre-commit hook ran"\n' \
> .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
echo a > f && git add f && git commit -qm one
# → pre-commit hook ran
echo b > f && git add f
GIT_CONFIG_COUNT=1 \
GIT_CONFIG_KEY_0=core.hooksPath \
GIT_CONFIG_VALUE_0=/dev/null \
git commit -qm two
# → (何も表示されない。hook は走らない)これは仕組みを見るための例です。Claude Codeが実際にどのキーを注入するかは、公式ページに載っていません。載っているのは「hook、資格情報ヘルパー、そのほかリポジトリの設定が起動できるプログラムを切る」という説明までです。
2.30以前のgitで同じ環境変数を付けても、設定は注入されずhookは走ります。evalが拒否している状況はこれです。
自分の環境が引っかかるか確かめる
まずバージョンを見ます。
git --version
which -a git注意するのは which -a のほうです。メッセージが指すのは「PATH上で最初に見つかるgit」で、同じマシンに新旧のgitが複数あると、新しい方を入れたつもりでも古い方が先に解決されることがあります。Xcode付属のgit、パッケージマネージャーのgit、独自にビルドしたgitが混在しやすい場面です。
CIのランナーは、手元とは別のgitが入っていることがあります。自分のランナーのイメージで git --version を一度出しておくと、手元では通るのにCIだけ落ちる差を早く見つけられます。
直し方
2.31以降のgitで再実行する
- 1
git を更新する
OSのパッケージマネージャーでgitを新しくします。公式ページの指示は「git 2.31以降を入れる」だけで、入れ方は指定していません。
- 2
PATH 上の git を確認する
which -a gitの先頭が新しいgitを指しているかを見ます。古い方が先なら、PATHの順序を直すか、古い方を外します。 - 3
同じコマンドを再実行する
claude plugin eval <dir>をやり直します。gitのバージョン確認を通れば、通常のcase実行に進みます。
更新後は claude plugin eval のオプションや設定を変える必要はありません。公式ページには、この検査を飛ばすフラグも載っていません。古いgitのまま走らせる逃げ道は、少なくともドキュメント上は用意されていません。
v2.1.283より前は何が違ったか
この拒否はv2.1.283(2026年9月25日)で入りました。changelogには「gitが入っている場合、claude plugin eval はgit 2.31以降を必須にする。古いgitでの実行は、バージョン名つきのメッセージで拒否される」という趣旨の項目があります。
トラブルシューティングのページには、変更前の動作がはっきり書かれています。
v2.1.283の前後で変わったこと
v2.1.283 より前
gitのバージョンを確認しない。古いgitでは、hookなどが有効なままsuiteが走る。
v2.1.283 以降
gitが2.31未満なら、caseを走らせる前にexit 1で止まる。
この差は、アップグレード後に突然CIが落ち始める原因になります。それまで通っていたsuiteが、Claude Codeをv2.1.283以降に上げた途端にexit 1になるなら、pluginやcaseより先に、ランナーのgitを疑う順番です。逆に言えば、古いバージョンで取った過去のスコアは、hookが動いた状態の結果だった可能性があります。
gitが無い環境は止まらない
条件は「gitが入っているなら」です。gitがPATHに無い環境では、この検査自体が働かず、evalは通常どおり実行されます。
ただし、caseがgitリポジトリを前提にしている場合は話が別です。scaffold_script でリポジトリを作るcaseや、git状態を読むpluginは、gitが無ければそもそも成立しません。バージョン検査を避けるためにgitを外すのは、評価したい内容を壊す選択になります。
CIでexit 1が出たときの切り分け
exit 1は「スコアが閾値に届かない」以外にも多くの原因で返ります。公式の終了コード表では、caseのスコア不足、caseファイルの読み込み失敗、caseが見つからない、runを起動できない、APIエラーでrunが終わった、ディレクトリが信頼されていない、オプション不正、--json の書き込み失敗などが同じ1に入っています。
結果の数字に問題がないのにexit 1になるときは、stderrに原因を示す1行が出ます。--json を付けていても出るので、CIのログで次を探します。
| stderrに見えるもの | 原因の方向 | 次にやること |
|---|---|---|
git X.Y is too old for claude plugin eval | 原因の方向ランナーのgitが2.31未満 | 次にやることgitを更新、PATHの順序を確認 |
| ディレクトリが未信頼で確認を出せないため拒否したという行 | 原因の方向初回でディレクトリが未信頼 | 次にやること端末で一度実行するか --trust-plugin |
| caseが見つからないという行 | 原因の方向caseディレクトリが無い、フィルタ不一致 | 次にやることpluginルートで実行、--case --tag を確認 |
gitの件は、モデルを1回も呼ばずに終わる点が特徴です。ログにコストの行やcaseごとのスコアが一切出ていなければ、このエラーを最初に疑えます。CI全体の合否の読み方はaggregate-result.jsonの記事にまとめています。
Dockerで動かすときの注意
コンテナでevalを回す場合、イメージのベースによってgitのバージョンが決まります。ベースイメージを固定していると、Claude Codeだけ更新してgitが古いままになる状況が起きやすくなります。Dockerfile側でgitのバージョンを明示するか、ビルド時に git --version を出して記録しておくと、原因の切り分けがすぐ済みます。
Docker入りのMacでBashつき実行が拒否される別の問題はsymlinkの記事で扱っています。こちらはgitのバージョンではなく、Dockerが置くシンボリックリンクが原因です。
無効化されるものが評価にどう関わるか
evalのrunは、ユーザー設定、hook、CLAUDE.md、MCPサーバー、ほかのプラグイン、メモリ、スキルが読み込まれない隔離環境で走ります。公式ページは、環境のほとんども渡さず、許可リストと EVAL_* の変数だけを通すと説明しています。
gitのhookと資格情報ヘルパーの無効化は、この隔離と同じ考え方です。runの結果を、手元の .git/hooks やログイン済みの資格情報に左右させない。そのための前提がgit 2.31以降、という考え方です。
別の面からも見ておきます。公式ページは、自分で書いていないhookを含むpluginを評価するときや本物のMCPサーバーを起動するときは、コンテナやCIランナーのような隔離環境でなければスコアは参考値として扱うよう書いています。hookやサーバーはエージェントのサンドボックスの外で動き、採点が読むファイルを書き換えられるからです。gitの検査はリポジトリ側の設定に由来する実行を止めるもので、plugin自身のhookを止めるものではありません。両者は別の話です。
evalの全体像とcaseの書き方はclaude plugin evalの使い方にあります。
まとめ
このエラーは、evalの実行環境を汚さないための入口検査です。直すのはpluginでもcaseでもなく、PATH上のgitです。Claude Codeを更新した直後にCIだけが落ち始めたら、まずランナーで git --version と which -a git を出してください。ログにスコアもコストも出ていなければ、ほぼこの件です。