Claude Media
Claude Codeの--debugと/debugの使い方 — ログの場所と--debug-file

Claude Codeの--debugと/debugの使い方 — ログの場所と--debug-file

Claude Codeのデバッグモードを有効にする--debugと/debugの違い、ログの保存先、--debug-fileでの出力先指定とカテゴリ絞り込みを扱います。

Claude Codeの--debugは、セッション内部の動作をログファイルに書き出すデバッグモードを有効にするフラグです。=で値をつなぐと、mcpやstartupのようなカテゴリだけに絞れます。--debug-fileは出力先のパスを直接指定するフラグで、指定するだけでデバッグモードも有効になります。

どちらも画面には何も出さず、ログはファイルにだけ書かれます。使い始めに迷いやすいのは、この「どこに書かれるのか」と「いつから記録されるのか」の2点です。

ログを出す4つの方法と、記録が始まるタイミング

デバッグログを有効にする手段は4つあり、出力先の決め方と、記録の始まる時点が違います。

手段

デバッグログを有効にする4つの手段

  • --debug

    起動時から記録します。出力先は既定の~/.claude/debug/<session-id>.txtで、=でカテゴリを絞れます。-dという短い形も使えます。

  • --debug-file <path>

    出力先を指定した場所に固定します。この指定だけでデバッグモードも有効になるため、--debugとの併用は要りません。

  • DEBUG=1

    --debugと同じ効果を環境変数で与えます。フラグを渡しにくいスクリプトやCIで使います。有効になるのは1・true・yes・onだけです。

  • /debug [説明]

    起動済みのセッションの途中から記録を始めます。--debugなしで起動していれば、実行した時点より前のログは残りません。

DEBUGが真偽値だけを受け付けるのは、他のツール向けにDEBUG=express:*のような名前空間パターンをシェルに設定していても、Claude Codeのデバッグモードが意図せず有効にならないようにするためです。

起動前の挙動を追いたいなら、最初から--debugか--debug-fileを付けて起動します。

似た名前の--verboseは別物です。claude --helpには「設定ファイルのverboseモードを上書きする」と書かれており、出力先を指定できるフラグではありません。画面の詳細表示を切り替えたいときは--verbose、あとから追える記録を残したいときは--debugか--debug-fileと使い分けます。

画面に何も出ないときは、ログの場所を探す

--debugを付けても、ターミナルには何も表示されません。想定どおりの挙動で、ログは既定なら~/.claude/debug/<session-id>.txtに書かれます。セッションごとにファイルが分かれるため、再開するたびに探し直すのが面倒なら、--debug-fileで固定のパスを指定しておくと同じファイルを開き続けられます。

保存先はCLAUDE_CONFIG_DIRにも従います。v2.1.289で、空のディレクトリをHOMEとCLAUDE_CONFIG_DIRに指定し、診断コマンドのclaude doctorに--debugを付けて実行したところ、ファイルは次の場所にできました。

export HOME=$(mktemp -d) CLAUDE_CONFIG_DIR=$HOME/cfg
claude --debug doctor > /dev/null
find $HOME -path '*debug*' -type f
/tmp/tmp.XXXX/cfg/debug/ee72b6dd-ec4a-4fff-a5b4-6292cb828830.txt

~/.claude/debug/ではなく$CLAUDE_CONFIG_DIR/debug/に作られています。複数アカウントをCLAUDE_CONFIG_DIRで切り替えている環境では、アカウントごとに別のディレクトリのログを見ることになります。

同じコマンドに--debug-fileを付けると、指定したパスにだけログができます。claude doctorが画面に出すのは診断結果だけで、デバッグログの行は混ざりません。出力先の優先順位は--debug-file、CLAUDE_CODE_DEBUG_LOGS_DIR、既定パスの順です。

CLAUDE_CODE_DEBUG_LOGS_DIRは名前にDIRと付いていますが、受け取るのはディレクトリではなくファイルパスです。この変数だけではログは出ず、デバッグモードを--debug・/debug・DEBUGのいずれかで別に有効にする必要があります。--debug-fileはパス指定と有効化を1つで済ませるので、単体で完結します。

カテゴリを絞るなら=でつなぐ

--debugは値なしでも使えますが、カテゴリを指定すると必要な行だけに絞れます。claude --helpの例は"api,hooks"と"!1p,!file"で、先頭に!を付けたカテゴリは除外されます。

くらべる

カテゴリの指定でフィルタが効くかどうか

効く

=でつなぐ

claude --debug='mcp,startup'と書くと、mcpとstartupに関するログだけを出します。シェルの解釈を避けるため、値はクォートで囲みます。

効かない

スペースで区切る

claude --debug mcp,startupと書くと、フィルタは結びつきません。カテゴリを絞らないデバッグモードが有効になるだけで、後ろの文字列は別の引数として扱われます。

フックが動いたかをログで確かめる

フックの起動確認では、出力先を決めておくと確認しやすくなります。--init-onlyと組み合わせると、セッションを開始せずにSetupフックとSessionStartフックだけを実行して終了します。成功しても画面には何も出ないため、ログで確かめます。

手順

フックの起動をログで確かめる

  1. 1

    出力先を指定して起動する

    claude --debug-file /tmp/claude-init.log --init-only
  2. 2

    ログファイルを開く

    /tmp/claude-init.logをエディタかlessで開きます。

  3. 3

    SetupとSessionStartの行を探す

    2つのフックについてのエントリがあれば、フックは実際に走っています。

ログレベルを変えて情報量を調整する

デバッグログに書き込む最小のログレベルはCLAUDE_CODE_DEBUG_LOG_LEVELで決まります。既定はdebugです。

レベル詳細度使いどころ
verbose詳細度最大使いどころステータスラインコマンドの出力全文など、高頻度な診断情報まで見たいとき
debug(既定)詳細度標準使いどころ通常のトラブルシューティング
info / warn詳細度抑制使いどころノイズを減らしたいが警告以上は残したいとき
error詳細度最小使いどころエラーだけを追いたいとき

フックについては、verboseにするとマッチャーの件数やクエリの照合といった細かい行が加わります。逆にログが多すぎて追えないときは、errorまで絞ります。ログは.txtのテキストファイルなので、[DEBUG]のようにレベル表記が付く行はgrep '\[DEBUG\]'で絞れます。

/debugで実行中のセッションを調べる

/debugはセッションの中で打つスラッシュコマンドで、公式にはバンドルされたスキルとして扱われます。デバッグログを有効にし、そのセッションのログを読んで問題を診断させます。

/debugのあとに症状を書くと、分析がその内容に絞られます。たとえば/debug MCPツールが表示されないのように使います。--debugなしで起動していた場合、記録されるのは実行した時点からです。

起動時の挙動まで追いたいなら、claude --debugで起動し直す方が確実です。

症状ごとに、どのログを見るか

カテゴリ絞り込みが効くのは、原因の見当がついている場面です。

MCPサーバーが接続済みなのにツールを1つも返さないときは、claude --debug=mcpで起動します。サーバーのstderrがデバッグログに残るので、失敗の手がかりをここで読めます。MCP接続そのものが失敗している場合の切り分けは、MCPサーバーに接続できないときの切り分け手順で層ごとに扱っています。

Hooksが発火しない、期待どおりに終了コードを返さないときは、カテゴリを絞らない--debugで、イベントごとのマッチャー照合と終了コードを見ます。ログには[DEBUG] Hook output does not start with {, treating as plain textのような行が出て、フックの出力がどう解釈されたかが分かります。種類ごとの挙動やイベント一覧はClaude Code Hooks完全ガイドにあります。

失敗の理由がデバッグログにしか残らないフックもあります。

  • ConfigChangeフックが設定変更をブロックしたとき、メッセージはユーザーにもClaudeにも出ず、デバッグログに一行だけ記録されます
  • register_repo_root経由で作業ディレクトリを追加したときのsystemMessageや失敗時の出力も、デバッグログにだけ書かれます
  • 非同期フックが返したJSONに型の違うフィールド(文字列でないsystemMessageなど)があると、そのフィールドだけが捨てられ、--debugで警告が見えます
  • PowerShellのフックに$CLAUDE_PROJECT_DIRをそのまま書くと、未定義のローカル変数として$nullに解決されます。書き換えは行われず、デバッグログに警告が出ます

設定まわりにも、画面に出ずにログにだけ警告が残る場面があります。

  • プロジェクト設定やローカル設定のenvに、リポジトリの持ち主が制御すべきでない変数を書くと、その値は読み飛ばされ、claude --debugで警告が見えます
  • spinnerTipsOverrideのtipsに不正なエントリがあると、設定ファイルごとは拒否されず、そのエントリだけがデバッグ警告つきで落とされます
  • WindowsでCLAUDE_CODE_GIT_BASH_PATHのパスが存在しない場合は、変数を無視してGit Bashを自動検出し、警告が--debugで見えます
  • OpenTelemetryのエクスポーターがPrometheusのポート衝突などで失敗するときは、既定ではデバッグログにだけエラーが出ます。CLAUDE_CODE_OTEL_DIAG_STDERR=1を設定すると、stderrにも出せます
  • スペルチェックが期待した辞書を使っているかは、--debugで起動して単語を入力し、ログの[spellcheck]行で調べます

起動そのものが拒否されるケースでは、--debugのログを開く前に、CLAUDE_CODE_STARTUP_FAILURE_RESULTSでstream-json出力に理由を書かせる方法もあります。設定値がどのスコープで上書きされているかを含めた切り分けは、Claude Code設定が反映されない原因の探し方が広く扱っています。

溜まったデバッグログの片付け方

--debugを常用すると、セッションごとにファイルが増えます。debug/ディレクトリには、デバッグログが起動のたびに別のファイルとして残ります。古いログを手でrmするほか、プロジェクト単位の掃除コマンドでも消せます。

プロジェクト単位の掃除はclaude purgeです。公式の説明では、プロジェクトの会話履歴・自動メモリ・タスク・ファイル編集履歴とあわせて、そのセッションのdebug/も消えます。デバッグログだけを消すコマンドではないため、先に--dry-runで対象を一覧します。

claude purge ~/work/repo --dry-run

claude purge --help(v2.1.289)のオプションは--dry-run、-i(1件ずつ確認)、-y(確認の省略)、--all(全プロジェクト)です。

/doctorと--debugはどちらから見るか

claude doctorと/doctorは、インストールの状態や設定ファイルの検証エラーを診断するコマンドです。claude doctorは読み取り専用で、セッションを開始せずに診断結果を出します。/doctorはセッションの中で、修正まで行えます。

実行中のセッションが何をしているかを追うのは--debug系の役割です。設定が読み込まれているかを疑うときはdoctor、読み込まれたあとの挙動を疑うときは--debugから入ります。

カテゴリで当たりを付け、--debug-fileで証跡を残す

MCPやHooksの不具合は、まずカテゴリを絞った--debugで当たりを付け、再現条件が固まったら--debug-fileで証跡を残す流れが扱いやすい組み合わせです。再現手順を他の人に渡すときも、ログの場所を--debug-fileで決めておけば、コマンドと一緒に伝えられます。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/cli-reference
  2. code.claude.com/docs/en/env-vars
  3. code.claude.com/docs/en/debug-your-config
  4. code.claude.com/docs/en/hooks
  5. code.claude.com/docs/en/commands
  6. code.claude.com/docs/en/settings-reference
この記事を共有:XはてブLinkedIn