Cron/loop jobs never fire while a background Bash task is running (stream-json clients only)

Status Open
Reported on v2.1.222
Maintainer reply None cached
Activity 1 comment · opened Aug 12, 2026

Summary

Scheduled jobs created with CronCreate (i.e. /loop <interval> …) are never delivered while a harness-tracked background Bash task is running, in clients that drive Claude over stream-json (VS Code extension, desktop app). The identical repro in a terminal CLI session delivers on cadence.

The job is not dropped — it stays listed and healthy in CronList the whole time, and ticks resume within seconds of the background task exiting. There is no error or warning, so an inert loop is indistinguishable from a working one.

This matters because the failing case is exactly the intended use case: arming a loop to watch a long-running job that was started in the background.

Repro

In a VS Code extension (or desktop app) session:

  1. Start a trivial background task through Claude's Bash tool (run_in_background: true), so the harness tracks it:

``
run this in the background: for i in $(seq 1 84); do echo "bg $i $(date +%H:%M:%S)" >> /tmp/bg.log; sleep 5; done
``

  1. Arm a one-minute loop:

``
/loop 1m Run exactly this and nothing else: echo "$(date +%H:%M:%S) tick" >> /tmp/ticks.log — then reply with only that line. No other tool calls.
``

  1. Send no further messages for ~5 minutes (user messages also suppress ticks, which would confound the result).
  1. cat /tmp/ticks.log

Expected: a tick roughly every minute.

Actual: no ticks at all until the background task exits. /tmp/ticks.log is not even created. CronList shows the job armed throughout.

Repeat the same steps in a terminal claude session for the contrast.

Observed

Same machine, same minute-granularity cron, same trivial sleep 5 background job launched the same way.

VS Code extension — background job alive 11:48:47 → 11:51:47:

11:49:10  cron armed
11:50:00  window — silent
11:51:00  window — silent
11:51:47  background job killed
11:52:21  tick          <- first line in the file, 34s after the kill

Terminal CLI — background job alive 11:54:57 → still running past 11:58:22:

11:55:12 tick   (manual first run by the /loop skill)
11:56:31 tick   <- cron fire, background job alive
11:57:31 tick   <- cron fire, background job alive

Also verified in the extension with a 4-minute background job and the session fully idle: 4 consecutive fire windows, zero ticks, ticks resumed after it exited. Load is not the factor — the background job is a sleep loop with negligible CPU and no disk activity.

Notes

  • ScheduleWakeup is affected identically, since it is implemented as a one-shot cron job (it appears in CronList as Every day at HH:MM (one-shot)).
  • An actively running turn suppressing ticks is expected and documented ("jobs only fire while the REPL is idle"). The issue is that a background task counts as non-idle in stream-json clients but not in the terminal.
  • The common factor across the failing clients appears to be the stream-json transport (--input-format stream-json --output-format stream-json), so SDK/headless runs may be affected too. Not verified.
  • Suggested fix direction: either make background tasks not block delivery in stream-json mode (matching terminal behaviour), or document the divergence and surface it — e.g. have CronList indicate that delivery is currently blocked.

Environment

  • VS Code extension anthropic.claude-code 2.1.222 (linux-x64), affected
  • Desktop app, affected
  • Terminal CLI on the same machine, not affected
  • Linux x86_64

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗