ScheduleWakeup re-fires slash commands, causing expensive duplicate runs
Summary
ScheduleWakeup re-executes the full slash command passed in its prompt field, with no safeguard against re-running expensive user-invoked commands. This caused an expensive multi-agent audit (/refactor:frontend) to run twice, and was on track to fire a third time, with no user consent between runs.
What happened
User ran /refactor:frontend once. The command spawns 4 parallel specialist sub-agents + 1 synthesis sub-agent and runs vitest/eslint/typecheck/npm-audit in the background — easily $1+ per run in token usage.
While waiting for the background vitest command to finish, Claude called:
ScheduleWakeup(delaySeconds=270, prompt="/refactor:frontend", reason="checking ...")
The intent was \"remind me to look at the background process.\" Instead, the harness re-fired the entire /refactor:frontend slash command at wakeup time, kicking off a complete second audit (4 specialists + synthesis, fresh timestamped directory, fresh background tool runs).
When that second audit completed, the final reply included another ScheduleWakeup(prompt=\"/refactor:frontend continue ...\"), which fired a third time. The user caught it before it could spawn a third full run.
User quote: \"this slash command is expensive to run, there's no scenarios where it's ok for you to rerun the command fully...they almost run it a third time\"
Why this is a footgun
ScheduleWakeuplooks like a polling/reminder primitive — name suggests \"wake me up later.\" It's actually a/loopdynamic-mode primitive that re-runs whatever string is passed asprompt.- No distinction between user-invoked slash commands and internal continuations. If
promptstarts with/, the harness should at minimum require explicit user re-consent, or refuse outright. - Tool description warns about cache TTL but not about re-execution cost. The docs explain the 5-minute cache window but don't warn that passing
\"/foo\"will re-run the user's/foocommand in full. task-notificationalready exists for the actual use case. Background-task completion firestask-notificationevents automatically — there's no need to schedule a wakeup to \"check\" on them.
Proposed fixes
- Refuse
ScheduleWakeupcalls wherepromptstarts with/unless the caller passes an explicitre_run_user_command=trueflag with a confirmation that the user has consented in this turn. - Strengthen the tool description: lead with \"this re-executes the prompt verbatim — passing a slash command will re-run the entire command including all sub-agents and tool calls. This is for
/loopdynamic mode only.\" - Add a guardrail hook that warns the model when
ScheduleWakeupis called with a/-prefixed prompt outside of/loopcontext.
Reproduction
- Invoke any expensive slash command (
/refactor:frontend,/ultrareview, etc.). - Inside that command, have Claude call
ScheduleWakeup(prompt=\"<same slash command>\")while waiting on a background process. - Watch the harness re-fire the whole command at wakeup time.
Environment
- Claude Code CLI
- Model: claude-opus-4-7 (1M context)
- Date: 2026-04-27
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗