Claude Codeで「The model's tool call could not be parsed」が頻発する問題の原因分析と対策
こんにちは!Qualitegプロダクト開発部です。
Claude Code(CLI)を使った開発中に、次のようなエラーが繰り返し表示されて作業が止まる現象に遭遇しました。
● The model's tool call could not be parsed (retry also failed).
リトライしても直らず、/clear で会話をリセットしても、しばらく作業を続けるとまた同じエラーが出るという状況です。本記事では、実際のセッションログ(jsonl)を解析して特定した原因と、その対策について共有します。
結論から書くと、これは利用者側の設定ミスやコンテキスト枯渇が原因ではなく、
Opus 4.7(1Mコンテキスト)+ extended thinking の組み合わせで発生する、モデル応答側のストリーミングバグ
でした。
現象
エラーが発生した環境は以下のとおりです。
- Claude Code 2.1.148
- モデル: Opus 4.7(1M context)
- プラン: Claude Max
- セッションの状態: Messages 371.7k / 1M tokens(使用率 約37%、空き58.5%)
- MCPサーバ: chrome-devtools のみ接続(2.3k tokens)
- CLAUDE.md: 22.7k tokens
- auto-compactは未発動
エラーは特定のツール呼び出しに紐づかず、Bash・Edit・MCP(chrome-devtools)など、どの直後でも発生しました。リトライしても同じエラーが返り、最終的に「retry also failed」として停止します。
最初は「会話が長すぎるのでは」「MCPツールが肥大化しているのでは」と疑いましたが、/context を確認すると空き容量が58.5%もあり、その仮説は成立しません。
セッションログから判明した正確な原因
決定的な手がかりは、Claude Code がセッションを保存している jsonl ファイルにありました。
保存場所はOSごとに異なります。
Windows
%USERPROFILE%\.claude\projects\<プロジェクト名>\<session-id>.jsonlmacOS / Linux
~/.claude/projects/<プロジェクト名>/<session-id>.jsonl<プロジェクト名> の部分は、作業ディレクトリのパスを区切り文字で変換した形式(例: C--Users-foo-projects-myapp) のようにドライブレターやスラッシュが - に置換された名前)になっています。ls や dir で該当ディレクトリを確認すれば、最近触ったセッションがファイル名で並んでいます。
このファイルを開き、parseエラーが起きた直前のassistantメッセージを確認すると、以下のような構造になっていました。
このファイルを開き、parseエラーが起きた直前のassistantメッセージを確認すると、以下のような構造になっていました。
{
"message": {
"model": "claude-opus-4-7",
"role": "assistant",
"content": [
{
"type": "thinking",
"thinking": "",
"signature": "..."
}
],
"stop_reason": "tool_use",
"stop_sequence": null
}
}
ここに3つの異常が同時に発生しています。
1. content配列が thinking ブロック1つしか含まれていない
通常であれば、thinking のあとに text ブロックや tool_use ブロックが続くはずです。しかしこのレスポンスには thinking だけしか入っていません。
2. thinking の中身が空文字列
"thinking": "" となっており、推論内容そのものが空です。signature フィールドは正しく付いているため、Anthropic API のサーバ側では「thinkingブロックを生成した」ことになっていますが、中身は空です。
3. stop_reason が tool_use なのに tool_use ブロックが存在しない
これが最も致命的です。stop_reason: "tool_use" はモデルが「ツールを呼ぶために停止した」ことを意味するシグナルですが、肝心の tool_use ブロックが content に含まれていません。
Claude Code のparserは「stop_reason が tool_use なら、content に tool_use ブロックがあるはず」という前提でレスポンスを処理します。しかし実際にはそのブロックが存在しないため、The model's tool call could not be parsed というエラーになり、リトライしても同じ壊れた応答が返ってくるため retry also failed となります。
つまり、Claude Code のクライアント側のバグではなく、Anthropic API(モデル)から返ってくるストリーミング応答そのものが不正だったわけです。
関連するAnthropic公式issue
このパターンは、anthropics/claude-code リポジトリの Issue #24662 で報告されている現象とほぼ一致します。同issueでは「ストリーミング中にthinkingブロック間に空のテキスト/thinkingブロックが挿入され、APIに再送できなくなる」事例が報告されています。
また、Mediumの記事「How I Stopped Getting Stream Idle Timeout Errors in Claude Code」(2026年4月)では、Opus 4.7のリリース以降、stream系のエラーが急増しており、4月中旬以降のissueでは Opus 4.7と1M contextバリアントを明示的にトリガーとして名指ししているものが複数あると報告されています。Anthropic側もこれを認識しており、Changelogにはstream-handling周りの修正が継続的に入っています。
原因の整理
事象を整理すると、原因は以下の組み合わせに集約されます。
| 要因 | 寄与度 |
|---|---|
| Opus 4.7 の応答ストリーミングのバグ | 核心 |
| extended thinking が default で xhigh(thinking-heavy) | 大 |
| 1M context バリアント | 中 |
| 長期セッション(cache_read 39万トークン超) | 中 |
特に強調したいのは、コンテキスト使用率や MCP の数は本件の主要因ではなかったという点です。/context で58%空いていてもエラーが発生していたのは、これが入力側の容量問題ではなく、出力側(モデル応答)の構造的なバグだからです。
Opus 4.7 はリリース時にデフォルト effort が xhigh に設定されており、thinkingブロックを多用する設計になっています。1M contextバリアントと組み合わさると、長い入力に対して thinking を吐く際にストリームが崩れやすくなる傾向があるようです。
対策
実際に有効だった対策と、その根拠を順に書きます。
1. effort を下げて thinking を抑える
/effort medium
または low。
Opus 4.7 のデフォルトは xhigh です。thinking-heavy な応答ほど、今回のような「空thinkingブロックでstop_reasonがtool_use」のような崩れ方が起きやすくなります。effort を下げることで thinkingの依存度を減らすのが、根本に近い対症療法です。
2. 1M context バリアントを無効化する
set CLAUDE_CODE_DISABLE_1M_CONTEXT=1
claude
公式ドキュメントにも記載のある環境変数です。1M context バリアント特有の出力崩れがあることがGitHub issueで複数報告されているため、これを切ることで再現条件のひとつを潰せます。標準の200kコンテキストの Opus 4.7 に戻ります。
3. 壊れたセッションは resume せず捨てる
このバグの厄介な点は、一度jsonlに壊れたassistantメッセージが書き込まれると、--resume や --continue で再開するたびに同じ壊れたメッセージが履歴として再送されることです。Claude Code 側の自動リトライも、サーバ側の応答が同じなら結果も同じです。
exit
claude # resume/continue は使わない
作業の継続性が必要であれば、CLAUDE.md か履歴ファイル(例: history/HANDOVER.md)に状態をスナップショットしておき、新規セッションで再開する運用にします。
4. Claude Code を最新版に更新する
claude update
2.1.148 → 2.1.150 にはstream-handling周りの修正が継続的に入っています。Anthropic公式もこの種のバグを認識しており、修正版がコンスタントに出荷されているため、なるべく最新を保つのが望ましいです。
5. Anthropicに /bug で報告する
これはAnthropic側のモデル/ストリーミングのバグなので、報告する価値が一番高い対策です。
/bug
session ID と request_id を添えて報告すれば、Anthropic側は該当リクエストのモデル応答を直接調査できます。クライアント設定の問題ではないため、ユーザー側でできる根本対策には限界があり、最終的にはAnthropicの修正を待つしかありません。
効かなかった/効果が薄かった対策
ついでに、最初に試したが効果が薄かった対策も書いておきます。
/clearで会話履歴をリセット: 一時的に止まるが、また数ターンで再発。原因がセッション履歴ではなくモデル応答そのものなので根本対策にならない。- MCPサーバを切る: 元々2.3k tokensしか使っていなかったので寄与が小さかった。MCPが肥大化している環境では有効。
/compact: コンテキスト使用率が低いため意味なし。
まとめ
「The model's tool call could not be parsed (retry also failed)」は、見た目こそ「ツール呼び出しのパースに失敗」ですが、実態はモデル側のレスポンスが構造的に壊れて返ってくる現象でした。
jsonl を確認すると、
contentに thinkingブロックしかない- thinkingが空文字
stop_reason: "tool_use"なのに tool_use ブロックが無い
という3点セットが揃っており、これがparserから見ると修復不能です。
今回特定できた現実的な対策は、
/effort mediumで thinking を抑えるCLAUDE_CODE_DISABLE_1M_CONTEXT=1で 1M context を切る- 壊れたセッションは resume せず捨てる
- Claude Code を最新版に更新
/bugで Anthropic に報告
の5つです。コンテキストが空いているのにこのエラーが頻発する場合、利用者側を疑うよりも先に、Claude Code のセッションログ(Windowsなら %USERPROFILE%\.claude\projects\、macOS/Linux なら ~/.claude/projects/)配下の jsonl を覗いてみることをおすすめします。アシスタント側の応答が空thinkingブロックになっていれば、本記事のケースと同じ症状です。
最後に補足ですが、この種のバグは Opus 4.7 のリリース以降に増えたもので、Anthropicも認識して継続的に修正を出している状況です。
長期的にはモデル/CLIのアップデートで解消が見込まれます。それまでは effort 設定と1M contextの扱いを調整して、なるべくバグを踏まない運用にするのが現実解になりそうです。
今回もお読みいただきありがとうございました。
何がお役に立てましたら幸いです
それでは、次回またお会いしましょう!