[BUG] Queued ScheduleWakeup silently dropped when a background Agent completion (or macOS sleep/wake) re-enters the session

Status Open
Reported on v2.1.197
Maintainer reply ✓ Yes — bcherny
Activity 5 comments · opened Jul 5, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

TL;DR

A pending ScheduleWakeup is silently dropped when its target time elapses while a background Agent (Agent tool, run_in_background: true) is still running. The session stays alive — the wakeup is not lost to a crash. Instead it appears to be absorbed by the Agent-completion notification path: when the background Agent finishes, its task-notification re-invokes the session, and the queued wakeup that should have fired during the Agent's run never fires.

A likely-related variant (same symptom, distinct trigger): a queued wakeup is also dropped across a macOS system sleep — the session survives the sleep/wake cycle but its self-paced loop never resumes, with no background Agent involved.

Impact: this silently ends a self-paced ScheduleWakeup loop. A swallowed reschedule means the next tick never happens, so the loop dies with no error and no user-visible signal.

Environment

  • Claude Code 2.1.197
  • VSCode extension
  • macOS (Darwin 25.5.0)

Reproduction — background-Agent trigger

  1. Start a self-paced ScheduleWakeup loop (each turn schedules the next wakeup).
  2. On some turn, also spawn a background Agent (Agent tool with run_in_background: true) whose runtime spans the next wakeup's target time.
  3. The harness confirms Next wakeup scheduled for ….
  4. The wakeup's target time passes while the Agent is still running — no fire.
  5. The Agent completes; its task-notification re-invokes the session.
  6. Observed: the queued wakeup never fired on its own; it is absorbed into the notification re-entry. The self-paced loop, which relied on that fire to reschedule, silently ends.

Transcript evidence (reproduced 2×)

  • (i) 02:57Z turn → 03:02Z wakeup target. No fire until a 03:16Z Agent-completion notification.
  • (ii) 04:07Z turn → 04:12Z wakeup target. No fire until 04:23Z.

In both cases the wakeup target elapsed mid-Agent-run and never fired independently.

Reproduction — sleep/wake variant (possibly same root cause)

  1. Start a self-paced ScheduleWakeup loop. No background Agent involved.
  2. Put the Mac to sleep spanning the next wakeup target (observed ~04:28–06:28Z).
  3. Wake the Mac. The session is still alive.
  4. Observed: the self-paced loop never resumes; the queued wakeup that came due during sleep never fires.

Expected

A queued ScheduleWakeup should fire on its own schedule (or fire promptly on the next re-entry) regardless of a concurrent background-Agent completion or a sleep/wake cycle. It should not be silently absorbed by the notification re-entry path.

Hypothesis

Both symptoms point to a single queued-wakeup timer that only one wake path can consume: an Agent-completion task-notification (or a sleep/wake resume) re-enters the session and clears/consumes the pending wakeup without firing it, so the loop's reschedule step never runs.

Timestamps + full transcripts available on request.

View original on GitHub ↗

3 Comments

mukdal · 3 months ago

Possibly-adjacent issues (none share this root cause — the swallowed-by-notification-re-entry mechanism — but flagging for triage):

  • #61735 — wakeup loss when the session process dies (crash/OOM). Distinct: here the session stays alive.
  • #57660 / #68198 — stale wakeup fires / no cancellation mechanism. Adjacent lifecycle handling.
  • #73389 — silent mid-turn drops on an idle/unattended Mac. May overlap with the sleep/wake variant above.

The common thread across these is fragile wakeup lifecycle around re-entry, termination, and idle/sleep — this issue adds the specific case of a concurrent background-Agent completion consuming the queued wakeup.

bcherny collaborator · 1 month ago

Thanks for the detailed report — reproduced on 2.1.233.

What I ran: an SDK/stream-json session (the transport the VS Code extension uses), scheduled a 60s ScheduleWakeup, then started a background Agent that outlived it. The wakeup did not fire at its target time; it fired only after the background agent completed and its completion notification had been processed (~2.5 min late in my run). So the wakeup isn't lost outright, but it is held for the entire lifetime of the background agent, and if Claude reschedules during the completion-notification turn, the overdue wakeup gets replaced by the new one — which is the "absorbed" behavior you saw. This is specific to SDK/IDE sessions: in the interactive terminal the same wakeup fires on time while a background agent runs.

We agree this is a bug — a scheduled wakeup shouldn't wait on unrelated background agents. We're looking at letting wakeups fire while the session is only waiting on background tasks.

The macOS sleep/wake variant we couldn't test here; if you can reproduce that one on its own, please open it separately with claude doctor output.

🤖 Generated with Claude Code

marcindulak · 23 days ago

For your information: the label reproduced on this issue does not prevent it from becoming stale and eventually auto-closed. See https://github.com/anthropics/claude-code/issues/87647 for details, and consider upvoting that for visibility.

Showing cached comments. Read the full discussion on GitHub ↗