Claude Media
Agent SDKのエラー集 — CLINotFoundErrorと構造化出力None

Agent SDKのエラー集 — CLINotFoundErrorと構造化出力None

Agent SDKのCLINotFoundError・CLIConnectionError・ProcessError・structured_output Noneの原因と対処をエラーメッセージ別に解説します。

Agent SDKのエラーの切り分け方

エラー文言の先頭を見れば、CLIの起動前・実行中・出力検証のどこで落ちたかが分かります。PythonとTypeScriptでは同じ失敗でも文言と例外の種類が違うため、先に使っているSDKを確認します。

手順

メッセージから原因の段階を絞る順番

  1. 1

    文言の先頭で3系統に振り分ける

    Claude Code not found / Native CLI binary ... not found / Refusing to execute batch script / Failed to start / Not connected はCLIの起動前後の失敗です。Command failed with exit code / process exited with code / returned an error result はCLIが実行中に終了した場合、structured_output が空なのに成功扱いは出力検証の問題です。

  2. 2

    Pythonか、TypeScriptかを確かめる

    Pythonは CLINotFoundError や ProcessError などの専用クラスを投げます。TypeScriptの多くはクラスの無い素の Error なので、メッセージ文字列で照合します。

  3. 3

    アプリが動く環境で `claude --version` を通す

    失敗している環境そのものの中で実行します。ローカルのシェルで通っていても、判断材料になりません。

フックが動かない、MCPサーバーが failed になる、スキルが読まれないといった機能単位の症状は、このページの対象ではありません。それぞれの機能ページに専用のトラブルシューティング節があります。Not logged in や 429 などのAPIエラーも別の「エラーリファレンス」の担当です。コンテナで「手元では動くのにデプロイ先で動かない」ときは、後述の起動エラーの節がそのまま当てはまります。

npm/pipのインストール自体でつまずく場合は、Claude Codeでよくあるエラー10選のインストール関連の節が対象です。DEBUG 環境変数を設定した途端にPython SDKだけが応答を受け取れなくなる症状は、起動エラーとは別物で、Agent SDKがDockerのDEBUG環境変数で動かなくなる原因と回避策にまとめています。

CLIが見つからない・起動できないエラー

CLINotFoundError: Claude Code not found(Python)

Python SDKは内部でClaude Code CLIをサブプロセスとして起動します。claude 実行ファイルが見つからないと、次のメッセージで CLINotFoundError が発生します。

Claude Code not found at: /your/configured/path

ClaudeAgentOptions(cli_path=...) でパスを指定していて、そのファイルが存在しない場合はメッセージにそのパスが含まれます。cli_path を指定していなければSDKは PATH と一般的なインストール場所を探索し、プラットフォーム別のインストール手順もメッセージに含めます。

対処は次の3点です。

  • Claude Code本体が未インストールなら先にインストールする
  • cli_path を指定している場合は、そのファイルが実在し claude 実行ファイル本体であることを確認する
  • PATH 解決に頼っている場合は、アプリケーションが実際に動く環境で claude --version が通るか確認する

IDEやサービスマネージャーから起動したプロセスは、シェルとは異なる PATH で動くことがあります。TypeScriptでは任意依存の省略か、pathToClaudeCodeExecutable のパスを確かめます。

Native CLI binary not found(TypeScript)

TypeScript SDKはバンドルされたプラットフォーム別パッケージと、pathToClaudeCodeExecutable で指定したパスからCLIを探します。表示されるメッセージによって原因が分かれます。

メッセージ原因対処
Native CLI binary for <platform>-<arch> not found原因同梱のプラットフォーム別パッケージが無い。インストール時に任意依存パッケージ(optional dependencies)をスキップした場合が多い対処任意依存を飛ばさずに @anthropic-ai/claude-agent-sdk を再インストールするか、pathToClaudeCodeExecutable でネイティブインストール先を指定
Claude Code native binary not found at <path> / Claude Code executable not found at <path>. Is options.pathToClaudeCodeExecutable set?原因解決したパスにファイルが存在しない、またはプロセスがアクセスできない対処パスの実在とアクセス権を確認

コンテナ向けのイメージビルドで任意依存を省いていると、1行目の文言になります。bun build --compile で単一実行ファイルにした場合は、同じ1行目の文言でも原因が違います。コンパイル後の実行ファイルの仮想ファイルシステム($bunfs)の中では、SDKが同梱バイナリを実行時に解決できません。

回避策は、プラットフォーム別バイナリをファイル資産として埋め込み、起動時に extractFromBunfs() で実在するパスへ取り出して pathToClaudeCodeExecutable に渡す方法です。

import binPath from "@anthropic-ai/claude-agent-sdk-darwin-arm64/claude" with { type: "file" };
import { extractFromBunfs } from "@anthropic-ai/claude-agent-sdk/extract";
import { query } from "@anthropic-ai/claude-agent-sdk";
 
const cliPath = extractFromBunfs(binPath);
 
for await (const message of query({
  prompt: "Hello",
  options: { pathToClaudeCodeExecutable: cliPath },
})) {
  console.log(message);
}

extractFromBunfs() は、コンパイルした実行ファイルの外では入力パスをそのまま返すので、同じコードを開発中にも動かせます。埋め込めるバイナリは1つの実行ファイルにつき1プラットフォーム分で、importするパッケージ名を --target に合わせます。別のプラットフォーム向けにクロスコンパイルするなら、たとえば npm install @anthropic-ai/claude-agent-sdk-linux-x64 --force で対象側のパッケージを入れます。Windowsではバイナリのサブパスが claude.exe です。

CLIConnectionError: Refusing to execute batch script(Windows)

Windowsで、Python SDKが使うCLIパスが .bat や .cmd のバッチスクリプト(npmインストールが作る claude.cmd シムを含む)を指していると、接続がこのメッセージで失敗します。

Refusing to execute batch script 'C:\Users\you\AppData\Roaming\npm\claude.cmd': Windows runs .bat/.cmd files via cmd.exe, which can execute commands injected through CLI arguments, and no reliable escaping for cmd.exe exists. Use a native claude executable instead: install Claude Code natively (irm https://claude.ai/install.ps1 | iex), point ClaudeAgentOptions(cli_path=...) at a claude.exe, or install the claude-agent-sdk wheel for a platform that bundles claude.exe (e.g. Windows x64).

この拒否は意図的なセキュリティ対策で、インストールが壊れているわけではありません。Windowsはバッチスクリプトの起動を cmd.exe /c 呼び出しに書き換えて実行し、cmd.exe は実行時にコマンドライン全体を再解析するため、引数の値経由でコマンドが注入される余地が生まれます。

ほとんどのWindows環境ではこのエラーに遭遇しません。claude-agent-sdk のWindows x64向けwheelには claude.exe が同梱されており、SDKはこの同梱CLI、次にディスク上のネイティブ claude.exe、最後にバッチシムの順で優先します。拒否が出るのは次の2ケースです。

  • ClaudeAgentOptions(cli_path=...) にnpmの claude.cmd シムなど、.bat/.cmd ファイルを指定している
  • ARM64 Windowsのソースインストールなど、同梱も単体もネイティブの claude.exe が無く、PATH 上の claude がnpmのシムだけになっている

cli_path を設定している間はSDKの探索自体がスキップされるため、この状態でClaude Code本体だけをネイティブ再インストールしても効果はありません。cli_path の指定を claude.exe に変更するか、指定そのものを外してSDKに探索させる必要があります。

対処はネイティブ実行ファイルを渡すことです。

  • cli_path を指定しているなら claude.exe を指すよう変更するか、オプションごと外す
  • PowerShellで irm https://claude.ai/install.ps1 | iex を実行してネイティブインストールする
  • x64 Windowsでは claude-agent-sdk のwheelをインストールする。claude.exe が同梱されている

CLIConnectionError: Failed to start Claude Code

パス解決には成功したものの起動できない場合のエラーです。Pythonは CLIConnectionError、TypeScriptはSDKクラスを持たないプレーンな Error としてメッセージを渡します。

メッセージSDK意味
Failed to start Claude Code: <detail>SDKPython意味detail部分はOS自体のエラー
Claude Code executable at <path> exists but failed to launchSDKTypeScript意味指定パスのスクリプトが実行できない
Claude Code native binary at <path> exists but failed to launchSDKTypeScript意味バイナリが実行できない(libcに関する示唆付き)
Failed to spawn Claude Code process: <detail>SDKTypeScript意味その他の起動失敗全般

両SDKに共通する典型的な原因は、解決したパスがテキストファイルやディレクトリ、実行権限のないファイルなど「実行できないもの」を指している状態です。対処は次の3点です。

  • 設定したパスが claude 実行ファイル自体を指し、実行権限があるか確認する
  • 独自パスが不要ならオプション(Pythonは cli_path、TypeScriptは pathToClaudeCodeExecutable)を外し、同梱のコピーを優先するSDK任せの探索に戻す
  • コンテナイメージ内でSDKに同梱されたバイナリが失敗する場合は、イメージビルド時にSDKを再インストールするか、実行するアーキテクチャ向けにイメージを作り直す

イメージのビルド中に実行権限が外れる場合もあります。TypeScriptの「native binary ... exists but failed to launch」に付くlibcの示唆は、アーキテクチャやlibcの不一致を疑う手がかりです。

CLIConnectionError: Not connected

Pythonで ClaudeSDKClient のメソッドを、接続前または切断後に呼び出すと発生します。

Not connected. Call connect() first.

メッセージの指示通り、他のクライアントメソッドを呼ぶ前に await client.connect() を呼ぶか、async with ClaudeSDKClient() as client: の形でクライアントを開いてください。後者は開いた時点で自動的に接続します。

プロセスが途中で終了したときのエラー

このセクションのエラーは、アプリケーションがCLIプロセスを使っている最中にプロセスが終了したことを意味します。どのエラーが出るかは言語と、CLIが終了前にエラー結果を報告していたかどうかで決まります。サブエージェントの進捗停止検知はCLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MSにまとめています。

くらべる

Pythonで届く2種類の終了エラー

エラー結果なしで終了

素のProcessError

CLIがエラー結果を報告しないまま終了したときの例外です。exit_code に終了コードが入ります。

エラー結果を報告して終了

ResultError

ProcessError のサブクラスです。subtype や terminal_reason などの属性に失敗の種類が入るため、メッセージを文字列で解析せずに分岐できます。

ProcessError: Command failed with exit code(Python)

Claude Codeプロセスが非ゼロの終了コードで終わると、Python SDKは ProcessError を発生させます。

Command failed with exit code 1 (exit code: 1)
Error output: Check stderr output for details

メッセージには終了コードが2回出ます。Error output の行は実際のプロセス出力ではなく固定文言で、例外の stderr 属性を読んでも同じ固定文言が返るだけです。実際にCLIがstderrへ書いた内容を取得するには、ClaudeAgentOptions に stderr コールバックを渡してログに記録してください。

ResultError は ProcessError のサブクラスなので except ProcessError で両方捕捉できます。扱いを分けたい場合は except ResultError を先に書きます。

ResultError: 失敗理由はterminal_reasonから読む(Python)

ResultError は、最終結果メッセージを返したあとにCLIがエラー結果で終了したときの例外です。ターン数の上限やAPIエラーが該当します。主な属性は次のとおりです。

属性中身
subtype中身"error_max_turns" "error_during_execution" など。最後のリクエストが失敗したときは "success"
terminal_reason中身"max_turns" "api_error" など。subtype より先に確認する
api_error_status中身APIエラーのHTTPステータス
errors / result中身結果メッセージが報告したエラーの一覧と本文
data中身結果メッセージの生のペイロード全体

subtype が success でも失敗している点が引っかかりやすいところです。最後のAPIリクエストが失敗した場合は subtype が "success" のまま、原因が terminal_reason の "api_error" に入ります。max_turns や max_budget_usd のように自分で設けた上限が実行を止めたときは error_* 系の subtype になります。この違いを踏まえた分岐は次のとおりです。

from claude_agent_sdk import query, ProcessError, ResultError
 
try:
    async for message in query(prompt="Hello"):
        print(message)
except ResultError as e:
    # terminal_reason を先に見る(API エラーは subtype が "success" で届く)
    reason = e.terminal_reason or e.subtype
    print(f"error result ({reason}): {e}")
except ProcessError as e:
    print(f"CLI exited with code {e.exit_code}")

Claude Code process exited with code N(TypeScript)

このメッセージ自体はIDE統合でも表示されますが、本節はAgent SDKのコードが受け取る形を扱います。TypeScript SDKは非ゼロ終了を素の Error として、query() のメッセージを回す for await ループを拒否(reject)する形で伝えます。専用のSDKエラークラスは無いため、ループを try/catch で囲みメッセージを照合します。

Claude Code process exited with code 1. stderr: <tail of the CLI's stderr>

CLIがstderrに書き込んでいた場合、メッセージの末尾にその末尾部分が付きます。ストリーム全体を取得したい場合はクエリオプションに stderr コールバックを渡してください。シグナルで強制終了した場合は同じ形式で Claude Code process terminated by signal <name> と表示されます。

IDE拡張がこの文言を出す場合は、終了コード単体では原因が分かりません。真のエラーはプロセス自身の出力にあります。同じプロジェクトで端末から claude を実行すると、実際のエラーメッセージ付きで再現することがあります。

Claude Code returned an error result(両SDK共通)

CLIが終了前にエラー結果を報告していた場合、両SDKともプロセス終了エラーの代わりにこのメッセージになります。

Claude Code returned an error result: <the CLI's own error report>

コロン以降がCLI自身のエラー報告なので、まずそちらを確認してください。終了コードより先にコロン以降を読みます。Pythonは前項の ResultError として送出するので、subtype や terminal_reason で分岐できます。TypeScriptは同じ内容のメッセージを持つ素の Error でメッセージループを拒否(reject)します。

構造化出力がNoneになるとき

structured_output is None but the result says success

結果メッセージが subtype: "success" で終わっているのに、Pythonでは structured_output が None、TypeScriptでは undefined のままになることがあります。実行自体は完了しますが、検証済みの出力は存在しません。原因の一例は、どんな出力でも満たせないスキーマ(長さの制約同士が矛盾しているなど)です。この場合も実行は完了するため、structured_output が空であることは自分で確認する必要があります。

アプリケーション側ではこの結果を失敗として扱ってください。subtype が success であることと structured_output が存在することの両方を確認してから使う実装が必要です。同じスキーマで繰り返し発生する場合は、スキーマが充足可能かどうかを検証し、いったん単純化してから制約を1つずつ戻していくと原因を切り分けやすくなります。

error_max_structured_output_retriesが返るとき

出力が検証を通らなかった場合は、subtype が success ではなく error_max_structured_output_retries になります。複数回の再試行のあとも有効な出力が残らなかった状態です。スキーマが複雑すぎる、タスクが曖昧、検証エラーの修正を繰り返して再試行の上限に達した、といった場合に起きます。

検証エラーが無いのに同じ状態になる経路もあります。自動モデルフォールバックが、完成済みの出力をストリームの途中で取り消し、再試行でも置き換わらなかった場合です。スキーマを疑って直し続ける前に、結果メッセージの errors リストを見て、どちらの原因かを先に分けます。

あゆみ

この記事のエラーに関わるSDKバージョン

  1. Python 0.2.124バッチスクリプトの起動を拒否

    これより前のPython SDKは、.bat/.cmd をチェックなしで cmd.exe 経由で起動していました。

  2. Python 0.2.140ResultError が登場

    これより前は、エラー結果での終了をプレーンな Exception として送出していたため、except ProcessError では拾えません。

  3. TypeScript 0.3.144extractFromBunfs() が使える

    bun build --compile した実行ファイルで同梱CLIを取り出す関数です。

この一覧に無いエラーに遭遇したら

上記に該当しないエラーは、使用しているSDKのGitHubリポジトリ(TypeScriptはclaude-agent-sdk-typescript、Pythonはclaude-agent-sdk-python)のissueを確認するか、新規に起票してください。報告時はエラーメッセージ全文とSDKのバージョンを含めると対応が早まります。

似た症状の個別記事もあります。cwdが反映されない症状はClaudeCodeOptionsのcwdが反映されない理由と回避策、大きな応答でCLIJSONDecodeErrorが発生する症状は大きいメッセージでJSONDecodeErrorが発生し停止する原因と対処で扱っています。特定バージョンでPyPIにwheelが公開されずインストールに失敗する症状は原因と対処法にあります。

エラーではなく仕様変更が原因のこともあります。システムプロンプトや settingSources の既定が変わった場合は、Agent SDK移行ガイドで変更点を確かめられます。最小構成で再現させるときの足場には、Agent SDKのサンプルと実例集が使えます。

まとめ

例外の型より、中に入っている情報に原因があります。terminal_reason、stderr コールバックの出力、errors リストを先に読みます。subtype が success でも失敗している場合があるため、成功の判定は structured_output の有無まで見ます。

この記事を共有:XはてブLinkedIn