[BUG] SessionEnd hook creates infinite recursive loop when spawning a claude CLI subprocess
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Severity: Critical (can silently drain API credits to zero)
Product: Claude Code — Hooks system (settings.json)
---
Description
The SessionEnd hook in Claude Code does not guard against recursive self-triggering. When the hook spawns a claude CLI subprocess (e.g., to run a logging agent), that
subprocess is itself a Claude Code session. When it terminates, it fires SessionEnd again — spawning another agent, which fires another SessionEnd, ad infinitum.
The loop only terminates when the API credit balance reaches zero.
---
Steps to Reproduce
- Add the following to .claude/settings.json:
{
"hooks": {
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "claude --print 'Log this session.' --allowedTools 'Write'"
}
]
}
]
}
}
- Close any Claude Code session.
- Observe: the hook fires, spawns a claude subprocess, which ends and fires SessionEnd again. The loop runs until credits are exhausted.
---
Observed Behavior
- 74 agent invocations in ~4 hours on June 4, 2026
- ~50,000,000 input tokens consumed (vs. ~82,000,000 for the entire previous month)
- Zero productive output
- Stopped only when API balance hit zero ("Credit balance is too low" in logs)
---
Expected Behavior
Either:
- (A) SessionEnd should not fire for subprocesses spawned by a SessionEnd hook itself, or
- (B) Claude Code should detect recursive SessionEnd triggering and break the loop after N iterations (e.g., 3), or
- (C) The documentation should explicitly warn: "Do not spawn a claude CLI subprocess inside a SessionEnd hook — this will cause infinite recursion."
---
Hook Configuration That Triggered the Bug
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "claude --agent session-logger --model claude-haiku-4-5 --print 'Log session.' --allowedTools 'Read,Glob,Write,Bash'",
"timeout": 130
}
]
}
]
---
Environment
- Platform: Linux VPS (Ubuntu), Claude Code CLI
- Shell: bash
- Hook type: SessionEnd
- Subprocess: claude CLI (claude-haiku-4-5)
---
Suggested Fix
Inject an environment variable (e.g., CLAUDE_HOOK_DEPTH=1) when Claude Code runs a hook command. If that variable is already set when a new session starts, suppress
SessionEnd hook execution for that session. This would cost zero user-visible behavior change for legitimate use cases.
What Should Happen?
Expected Behavior
Either:
- (A) SessionEnd should not fire for subprocesses spawned by a SessionEnd hook itself, or
- (B) Claude Code should detect recursive SessionEnd triggering and break the loop after N iterations (e.g., 3), or
- (C) The documentation should explicitly warn: "Do not spawn a claude CLI subprocess inside a SessionEnd hook — this will cause infinite recursion."
Error Messages/Logs
Steps to Reproduce
The SessionEnd hook in Claude Code does not guard against recursive self-triggering. When the hook spawns a claude CLI subprocess (e.g., to run a logging agent), that
subprocess is itself a Claude Code session. When it terminates, it fires SessionEnd again — spawning another agent, which fires another SessionEnd, ad infinitum.
The loop only terminates when the API credit balance reaches zero.
---
Steps to Reproduce
- Add the following to .claude/settings.json:
{
"hooks": {
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "claude --print 'Log this session.' --allowedTools 'Write'"
}
]
}
]
}
}
- Close any Claude Code session.
- Observe: the hook fires, spawns a claude subprocess, which ends and fires SessionEnd again. The loop runs until credits are exhausted.
---
Observed Behavior
- 74 agent invocations in ~4 hours on June 4, 2026
- ~50,000,000 input tokens consumed (vs. ~82,000,000 for the entire previous month)
- Zero productive output
- Stopped only when API balance hit zero ("Credit balance is too low" in logs)
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
v2.1.161
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗