Scheduled task from a closed session fires in another session as an unmarked user turn

Status Open
Reported on v2.1.289
Maintainer reply None cached
Activity 0 comments · opened Oct 9, 2026

Cron jobs from a closed session run in another session as unmarked user turns, and a finished one-shot can run twice

Version: Claude Code 2.1.289, macOS (Darwin), measured 2026-10-09.

Summary

Durable CronCreate jobs live in <project>/.claude/scheduled_tasks.json and any live session in that project directory can pick them up. Two behaviors follow from that, and neither is visible to the person at the keyboard.

(a) Delivery from a dead creator. When the session that created a durable job has closed, the job fires in a different live session in the same project directory. The prompt arrives as an ordinary user turn. Nothing says which session created it, that it is scheduled, or that it did not come from the person typing. It can land in a session that is busy with other work.

(b) Second fire. A one-shot (recurring: false) that has already run can remain in scheduled_tasks.json. Once the session that ran it closes, the same job fires again in another session.

Why it matters

  • A scheduled prompt is indistinguishable from operator input, so the receiving session (and the person reading its transcript) treats it as an instruction from the user. A prompt written for one session's context runs in an unrelated one.
  • A one-shot that repeats can redo work that was already done by hand or by the first run.

Repro

Setup: two Claude Code sessions, A and B, started in the same project directory.

(a)

  1. In A, create a durable one-shot a few minutes out with CronCreate (durable: true, recurring: false) and a harmless prompt, such as "reply with the word PING".
  2. Close A before the due time. Leave B open (idle, or in the middle of a task).
  3. Wait past the due time.
  4. Observed: the prompt appears in B as a user turn and B acts on it. Expected: it is either dropped, held for its creator, or clearly labelled as a scheduled prompt from another session.

(b)

  1. In A, create a durable one-shot as above and leave A open until it fires (observed 11:22 local).
  2. Check .claude/scheduled_tasks.json: the entry is still present after its run.
  3. Close A.
  4. Observed: the same prompt fires again in B (11:27:58 local). Expected: a one-shot is removed after it runs and fires once.

Related observation

An open, idle session that nobody is typing in does run a due durable job, so the job does not wait for a keypress. The action it runs still goes through the permission check, so an unattended prompt can stall there.

A 2026-09-04 observation of a durable job that did not fire for two hours in an idle session was not reproduced and is not part of this report.

Suggested behavior

  1. Label a delivered scheduled prompt in the transcript (source: scheduled, creating session id), so it cannot be read as typed input.
  2. Run a job only in the session that created it, or only after the creator is confirmed gone, and say so when it is delivered elsewhere.
  3. Remove a one-shot from scheduled_tasks.json when it fires, not when the creating session closes.

View original on GitHub ↗