Local scheduled tasks: silent no-trace failures, stall-then-burst late firing, alive-but-stalled fires, and missed-run ledger desync (4 incidents in 8 days, macOS desktop app)

Open 💬 0 comments Opened Jul 12, 2026 by MABernhardt

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Related: #55631 ("scheduler stops firing until restart").

Summary

I run ~37 local scheduled tasks (grandfathered folder-bound tasks predating the 2026-07-07 cloud-scheduler release) on the macOS Claude desktop app. Since 2026-07-05 the local scheduler has failed four distinct ways. The worst failure mode is silent: a task's session starts (or never starts), dies without writing anything, produces no error surface, and the scheduler records nothing actionable. The only way I discover dead fires is by noticing missing output files the next morning.

Environment

  • macOS desktop app, Claude Cowork scheduled tasks (local, folder-bound to a Google Drive folder)
  • ~37 enabled tasks, cron cadences between daily and monthly, firing 22:00–02:30 PT
  • App updated across the 2026-07-07 release (cloud scheduled tasks / remote sessions beta)

Incident 1 — 2026-07-05: missed overnight batch, single catch-up on wake

Overnight batch did not fire (Mac asleep); one catch-up per task fired ~05:05–05:20 PT on app wake. Known/old behaviour, listed for baseline.

Incident 2 — 2026-07-09, ~14:49–15:03 PT: missed-run catch-up storm + ledger desync

After an app update/restart, five weekly tasks fired within 15 minutes, each labelled "missed [date] run" with missed slots dating back 3–7 days (Jul 2/3/5/6) — i.e. the scheduler had been silently not-firing those slots for days, then flushed the backlog at once. Evidence of ledger desync: at least one task (weekly, due Thu 23:00 PT) had its missed slot "paid" by the 14:54 PT catch-up and then skipped its real slot entirely that same night, while two sibling weekly tasks fired both their catch-up AND their next real slot (double-paid).

Incident 3 — 2026-07-09/10 overnight: half the batch died silently, the rest fired in late bursts

14 tasks were due between 22:10 PT and 02:00 PT. Outcome by slot time:

  • 22:10–23:30 PT (7 tasks): all but one died silently. No output, no error, no trace. One crash was recovered: a task due 22:30 PT started on time (its session transcript shows two tool calls) then terminated with "API Error: Connection closed mid-response" and wrote nothing. status.claude.com shows no platform incident in this window, so the connection death appears local/app-side.
  • 00:00–02:00 PT (6 tasks): all fired, but 40 minutes to 2.5 hours LATE, completing in two bursts (~00:43 PT and ~02:40–02:48 PT) — consistent with the scheduler stalling and briefly reviving twice.
  • One daily task due 01:15 PT never fired at all and was not caught up.

Model assignment was ruled out: the dead window killed tasks on both Opus and Sonnet configurations; the revival bursts completed tasks on both.

Incident 4 — 2026-07-11/12 overnight: 8 of 9 fires produced nothing; several confirmed alive-but-stalled for 5–8+ hours

9 tasks were due between 22:30 PT and 01:15 PT. The Mac was on and awake the entire night (ruling out the sleep explanation from Incident 1). Only one task completed on schedule (a short, mostly-deterministic run, done 00:23 PT). The other eight produced no output by 05:00 PT. Crucially, a session-state check the next morning showed several of them dispatched on time and still in "running" state 5–8+ hours after their recorded lastRunAt (e.g. one dispatched 22:46 PT, still "running" at 07:11 PT) — alive but stalled, not crashed, with no failure surface either way. A manual restart of each at ~07:00 PT completed every one of them within minutes. So the same task body that hangs indefinitely overnight runs fine on manual re-dispatch: the failure is in the scheduled-fire dispatch/connection layer, not the tasks.

Related cloud-side gap — scheduled triggers cannot pre-approve connector tools

As a mitigation I built a cloud-side scheduled task (Claude Code Remote trigger) that watches the local scheduler's outputs via the Google Drive connector. It cannot run unattended: triggers created via the CCR MCP surface (create_trigger) get a fixed allowed_tools list (remote-devices bridge + CCR tools only), with no way to pre-approve connector tools (Google Drive, etc.). Every Drive call therefore blocks on a permission prompt that a human must click — on a task whose whole purpose is to run while the human is asleep. Ask: an API surface (or trigger option) to grant connector tools to a scheduled trigger.

Asks

  • Retry-with-backoff on connection errors for scheduled fires.
  • A per-task run history with explicit failure states (started-and-crashed vs never-attempted vs still-running vs completed), plus a max-runtime watchdog so an alive-but-stalled fire eventually fails visibly instead of hanging forever.
  • A fix for the stall-then-burst dispatch pattern (#55631 family).
  • Pre-approvable connector tools for cloud scheduled triggers (see cloud-side gap above).

Evidence available on request

File-mtime timelines for all four incidents, the recovered crash transcript reference, the task-by-task outcome table for the 2026-07-09/10 night, and session-state (still-running) observations for 2026-07-11/12.

What Should Happen?

  1. A task that fails should leave a visible failure record (in the scheduled-tasks UI and/or a machine-readable surface) — silent no-trace death is the worst possible failure mode for unattended automation.
  2. Missed slots should be caught up predictably (at most once, clearly labelled), without desyncing the schedule ledger (no skipped-next-slot, no double-pays, no multi-day silent accumulation followed by a burst).
  3. Scheduled fires should not die on "Connection closed mid-response" without a retry, and should not be able to hang in "running" state indefinitely without a max-runtime failure.

Error Messages/Logs

API Error: Connection closed mid-response
(recovered from the session transcript of a task due 22:30 PT on 2026-07-09: the session started on time, made two tool calls, then terminated with this error and wrote nothing; no failure surfaced in the scheduled-tasks UI)

Steps to Reproduce

  1. On the macOS desktop app, run a suite of local scheduled tasks (folder-bound to a Google Drive folder; ours is ~37 tasks with cron slots between 22:00 and 03:45 PT).
  2. Leave the Mac on and awake overnight (Incident 4 rules out sleep).
  3. Next morning, compare each task's expected output files against what was actually written, and check session states.
  4. Observe, across four nights in eight days, four failure shapes: fires that never started (no output, no error, no trace); fires that started then died on "API Error: Connection closed mid-response"; fires dispatched on time but stuck in "running" state 5-8+ hours later with nothing written; and missed-slot catch-up storms with ledger desync (skipped-next-slot and double-paid slots) after an app restart.
  5. Manually re-dispatch any dead fire the next morning: it completes within minutes, confirming the task bodies are fine and the failure sits in the scheduled-fire dispatch/connection layer.

Note: reproduction is probabilistic per night, but with a battery of overnight tasks it has occurred on 4 of 8 recent nights (2026-07-05, 07-09, 07-09/10, 07-11/12); details for each incident are in the description above.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

Claude desktop app 1.20186.1 (Cowork local scheduled tasks; not the CLI)

Platform

Other

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗