[BUG] ScheduleWakeup persists after Ctrl+C, daemon auto-respawns loop unattended causing unbounded token spend
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?
When a skill using /loop internally calls ScheduleWakeup, pressing Ctrl+C to interrupt the session does NOT cancel the pending wakeup timer. The Claude Code daemon auto-respawns the session and continues executing loop iterations indefinitely — even with the terminal closed and the Mac lid shut. This resulted in ~$300 of unintended API usage over a single weekend with no way to detect or stop it from the CLI.
What Should Happen?
Ctrl+C should cancel any pending ScheduleWakeup timers associated with the current session. The loop should stop when the user interrupts. There should also be a CLI command to list and kill active background jobs from any terminal.
Error Messages/Logs
~/.claude/jobs/e3b9dac0/state.json after Ctrl+C:
{"state": "working", "detail": "CDP triage complete (0 new bugs); next cycle 10:01", "tempo": "active", "inFlight": {"tasks": 2, "queued": 0, "kinds": ["session_cron"]}}
~/.claude/daemon/roster.json showed worker respawned with new PID after killing it:
{"attempt": 2, "pid": 35341, ...} — supervisor restarted it on exit 143 (SIGTERM)
CronList → empty. TaskList → empty. No CLI way to detect the running loop.
Steps to Reproduce
---
Steps to Reproduce
- Run any skill via
/loopwith a short interval (e.g./loop 5m /my-skill) - Press Ctrl+C to stop — you expect the loop to be cancelled
- Close the terminal window
- Check ~/.claude/daemon/roster.json — the worker entry persists
- The daemon continues running loop iterations unattended indefinitely
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.160
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Enterprise plan ($3,000/month limit). Loop ran ~864 iterations over a weekend (5 min interval × ~72 hours). The only workaround was manually editing ~/.claude/daemon/roster.json to set "workers": {} and ~/.claude/jobs/<id>/state.json to "state": "completed". This is a financial safety issue — users have no reasonable way to know the loop is still running after Ctrl+C.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗