Claude Code の SessionEnd hook から claude コマンドを呼ぶと無限ループになる

作成日:
Claude-Code hooks automation incident

概要

Claude Code の SessionEnd hook から claude -p コマンドを呼び出すと、無限ループが発生してトークンが枯渇する。SessionEnd hook にはシェルスクリプト・外部コマンドのみを書くべきであり、claude コマンド(スキル・エージェント呼び出し)を含めてはならない。

問題のある設定

セッション終了時にスキルを自動起動しようとして、以下のような hook 設定を行うと危険。

"hooks": {
  "SessionEnd": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "claude -p '/my-skill'",
          "async": true
        }
      ]
    }
  ]
}

なぜ無限ループになるか

claude -p は新しい Claude Code セッションを起動する。その新しいセッションが終了するときにも、同じ SessionEnd hook が再び発火する。

1. セッション A 終了
   └─ SessionEnd hook 発火
        └─ claude -p '/my-skill' 実行
             └─ 新セッション B 起動
                  └─ スキル実行 → セッション B 終了
                       └─ SessionEnd hook 発火
                            └─ claude -p '/my-skill' 実行
                                 └─ 新セッション C 起動
                                      └─ ...(無限ループ)

hook のスコープが「そのセッションのみ」ではなく、システム全体のすべての Claude セッション終了時に適用されるため、このような再帰構造が生まれる。

実害

  • ループが収束するまで Claude セッションが連鎖的に起動し続ける
  • 大量のトークンが消費され、トークン枯渇が発生する
  • 手動で hook 設定ファイルを編集して削除しない限り止まらない
  • Extra usageを無制限にしていたら、と考えるとゾッとする・・・

設計ルール

種類SessionEnd hook への記述
シェルスクリプト✅ 安全
外部コマンド(git, curl など)✅ 安全
claude -p(スキル起動)❌ 無限ループになる
claude CLI 全般❌ 無限ループになる

Claude Code が Claude Code を起動するコマンドを hook から呼ぶと、再帰構造になる。

代替パターン: キーワードによる手動起動

セッション終了時の自動記録など「セッション終了をトリガーにしたい処理」は、キーワードによる手動起動に置き換える。

  • ユーザーが「記録して」「保存して」「今日はここまで」などのキーワードを発話する
  • それをトリガーにスキルが起動する

完全自動化には一手間増えるが、ループのリスクがなく安定して動作する。

関連トピック

参考