ScheduleWakeup re-fires slash commands, causing expensive duplicate runs

Resolved 💬 3 comments Opened Apr 27, 2026 by msantana09 Closed May 30, 2026

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

  1. ScheduleWakeup looks like a polling/reminder primitive — name suggests \"wake me up later.\" It's actually a /loop dynamic-mode primitive that re-runs whatever string is passed as prompt.
  2. No distinction between user-invoked slash commands and internal continuations. If prompt starts with /, the harness should at minimum require explicit user re-consent, or refuse outright.
  3. 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 /foo command in full.
  4. task-notification already exists for the actual use case. Background-task completion fires task-notification events automatically — there's no need to schedule a wakeup to \"check\" on them.

Proposed fixes

  1. Refuse ScheduleWakeup calls where prompt starts with / unless the caller passes an explicit re_run_user_command=true flag with a confirmation that the user has consented in this turn.
  2. 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 /loop dynamic mode only.\"
  3. Add a guardrail hook that warns the model when ScheduleWakeup is called with a /-prefixed prompt outside of /loop context.

Reproduction

  1. Invoke any expensive slash command (/refactor:frontend, /ultrareview, etc.).
  2. Inside that command, have Claude call ScheduleWakeup(prompt=\"<same slash command>\") while waiting on a background process.
  3. 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

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗