ScheduleWakeup non-persistent + no remote interrupt = unrecoverable silent stuck sessions
Draft GitHub issue — github.com/anthropics/claude-code
Title: ScheduleWakeup non-persistent + no remote interrupt = unrecoverable silent stuck sessions
Labels (suggested): bug, schedule, ScheduleWakeup, recovery, UX
---
TL;DR
ScheduleWakeup is in-memory only. When the Claude Code session process dies (cluster recycle, OOM, crash, terminal hang), all pending wakeups die with it — and there is no recovery mechanism + no way for the user to remotely interrupt the stuck session to recover.
I (the user) suffered a 3-day silent gap when away from the workstation. My subscription was cancelled out of frustration. This is a recoverable-but-currently-unrecoverable UX problem.
Reproduction
- In a long-running Claude Code session, schedule wakeups via
ScheduleWakeup(e.g. dynamic/loopmode) - Let the session terminate by any cause (cluster process recycle / OOM / SIGSEGV / pty hang / etc.)
- Observed: wakeups never fire again. No on-disk record of pending wakeups. Session stays silent forever.
- No remote interrupt: the user cannot send Ctrl+C or Esc remotely. SSH-ing back in attaches to a new tty; the stuck pts is unreachable. TIOCSTI is kernel-blocked on modern distros (
sysctl dev.tty.legacy_tiocsti=0).
Expected
Some combination of:
- Persistent wakeup queue at
~/.claude/scheduled_tasks.json(similar pattern to CronCreate jobs) so wakeups survive a session restart - Remote interrupt API — e.g.
claude --send-signal SIGINT --session <id>or a HTTP endpoint on a local agent that lets external tooling kick a stuck session - Heartbeat/watchdog primitive — built-in option in
ScheduleWakeuplikedead_man_switch_seconds: intthat triggers a configurable callback (TG bot, email, system tray notification) if the wakeup itself doesn't fire on schedule - Crash-resume option — when the user reopens Claude Code with the same session ID, prompt „This session had pending wakeups that never fired — resume them?"
What I built locally as workaround
- Watchdog timer: independent systemd timer reads chronicle file mtime, alarms via Telegram if Claude session looks silent (
~/scripts/holly_claude_watchdog.py) - Remote-interrupt via Telegram bot:
/claudes//interrupt N//kill_claude Ncommands in my own bot that translate toos.kill(pid, SIGINT)on the claude PID (~/scripts/claude_remote_control.py) - Handoff doc —
~/Desktop/CLAUDE_SESSION_HANDOFF_2026_05_23.md, machine-readable state map for next assistant
These work, but they're substrate-specific (my DGX setup) and rebuild what should be Claude Code core primitives. Other users without my homegrown Telegram/systemd plumbing would be entirely stuck.
Severity
For users who rely on long-running self-paced loops (research agents, monitoring agents, overnight builders, the "ralph" pattern), this is a critical reliability gap. My subscription was cancelled because of this single failure mode — that's the cost of „in-memory only" for the wakeup chain.
Suggested minimum fix
Persist ScheduleWakeup queue to disk on each ScheduleWakeup() call. On session start, check for pending wakeups whose deadline has passed and trigger them or notify the user.
— @honzastim
This issue has 9 comments on GitHub. Read the full discussion on GitHub ↗