Background shell reminders persist after KillShell, causing context exhaustion
Bug Description
When a background shell is started with run_in_background: true and later killed with KillShell, the system continues to inject reminder messages on every single turn for the rest of the conversation. This rapidly exhausts context and makes long sessions unusable.
Steps to Reproduce
- Start a background shell:
{
"command": "npm run dev",
"run_in_background": true
}
-
Receive response:
Command running in background with ID: f0f238 -
Kill the shell:
{
"shell_id": "f0f238"
}
-
Receive confirmation:
Successfully killed shell: f0f238 -
Bug: On every subsequent turn, system injects reminders like:
Shell f0f238 has new output available. Use BashOutput to retrieve it.
Impact
- Context exhaustion: Each reminder adds ~150-200 chars per zombie shell
- Accumulates rapidly: With multiple background shells, adds 1000+ chars per message
- Cannot be cleared: No way to stop reminders without starting new conversation
- Session unusable: Long debugging sessions become impossible
Root Cause Analysis
Investigated the issue thoroughly:
- Background shell state is stored in conversation context (JSONL file)
KillShellkills the process but doesn't update conversation state- Conversation is append-only - past entries cannot be modified
- Reminder system checks conversation history, finds
backgroundTaskId, sends reminder - Even though shell is dead, the historical reference triggers reminders forever
Evidence from Conversation Log
// Shell started
{"backgroundTaskId":"f0f238"}
// Shell killed (success)
{"message":"Successfully killed shell: f0f238","shell_id":"f0f238"}
// But reminders continue on EVERY turn after this
Expected Behavior
After KillShell succeeds:
- No more reminders for that shell ID
- Shell should be marked as terminated in tracking state
BashOutputfor killed shell should return "Shell was terminated" not trigger reminders
Workarounds (None Effective)
| Attempted | Result |
|---|---|
KillShell |
Process dies, reminders continue |
fuser -k <port> |
Process dies, reminders continue |
Delete ~/.claude/shell-snapshots/* |
No effect |
Delete ~/.claude/session-env/* |
No effect |
| Any settings change | No relevant setting exists |
Only fix: Start a completely new conversation (loses all context).
Suggested Fix
- Track killed shells in session state (not just conversation history)
- Before sending background shell reminders, check if shell was killed
- Or: Add a way to clear/acknowledge background shell notifications
- Or: Add setting to disable background shell reminders entirely
Environment
- Claude Code version: 2.0.60
- OS: Linux (WSL2)
- Shell: bash
Severity
High - This makes background shells essentially unusable for any session longer than a few turns. The workaround in docs says "don't use background shells" but that defeats the purpose of having the feature.
This appears to be a duplicate of #11716, #12813, #13091, #7479, and others. This bug has been reported multiple times since at least September 2025 and remains unfixed. Adding my detailed root cause analysis to help with the fix.
Found 3 possible duplicate issues:
- https://github.com/anthropics/claude-code/issues/12813
- https://github.com/anthropics/claude-code/issues/12659
- https://github.com/anthropics/claude-code/issues/11716
This issue will be automatically closed as a duplicate in 3 days.
- If your issue is a duplicate, please close it and 👍 the existing issue instead
- To prevent auto-closure, add a comment or 👎 this comment
🤖 Generated with Claude Code
Ran into this exact issue today. Killed multiple background shells and the reminders kept flooding context. The result: 35% of weekly Opus quota burned in a few hours just from the context pollution.
We're planning to implement a PostToolUse hook as a workaround - it will detect repeated 'killed/terminated' patterns and excessive output size, then block before more Opus tokens get wasted.
The irony: the actual productive work (Sonnet indexing 595 files multiple times) only used ~8% of Sonnet quota. The context pollution from killed shells hitting the Opus conversation is what destroyed the budget.
Platform: Windows with WSL2