[BUG] A running workflow leaves no record on disk, so liveness cannot be checked and dispatch collides

Status Open
Reported on v2.1.247
Maintainer reply None cached
Activity 0 comments · opened Aug 27, 2026

Environment

  • CLI 2.1.247, macOS darwin-arm64, Max 20x, main loop Opus 5
  • Also present on 2.1.246

What happens

The run record at ~/.claude/projects/<slug>/<session>/workflows/wf_<id>.json is created when the run ends, not when it starts. While a workflow is running there is nothing in that directory representing it.

The practical effect is that the only obvious way to ask "what is running right now" always answers "nothing." A session that checks before dispatching sees an empty or all-completed directory and concludes the fleet is drained, then launches a second run onto work already in flight.

Evidence

Across 139 recorded runs on this machine, comparing each JSON file's birth time to the startTime field it contains:

run                    status     born-start  json-last        dur
wf_914c1b85-8d1        completed     7528.8s      0.0s   7528.8s
wf_5922a0b7-acf        completed     5521.0s      0.0s   5521.0s
wf_b4b251b7-eb8        completed     2114.5s      0.0s   2114.5s
wf_758eba10-c9c        completed     1880.8s      0.0s   1880.8s
wf_5f704081-cf5        completed     1799.3s      0.0s   1799.3s
...
json created after half the run had elapsed: 100 of 100 measurable runs

born-start equals the run duration exactly in every case, and the file is never modified after creation (json-last is 0.0s against the last transcript write). So the file is not created at launch and updated, it is created once, at completion.

The first row is a run that went 2 hours 5 minutes with no on-disk record of its existence at any point during it.

Status values observed across 400 sampled files: 133 completed, 3 killed, 3 failed, 261 with no status field at all (older format). No value ever represents a run in progress.

Impact

On 2026-08-23 this produced a wrong conclusion ("fleet drained") while 12 workflows were running, and the next dispatch collided on a unit already being worked. It is a silent failure: the directory is not empty in a way that looks broken, it looks like a clean finished history.

It also interacts badly with compaction. A compacted session has lost its in-memory handles, so disk is the only place left to look, and disk is exactly where a live run does not appear.

Ask

Either one of these fixes it:

  1. Write wf_<id>.json at launch with a status of running, and update it on completion. This is the smaller change and makes the existing directory answer the question correctly.
  2. Ship a claude workflows status / claude tasks list that reports live runs.

Workaround

Live runs are observable, just not where you would look. The transcript directory is created at launch:

~/.claude/projects/<slug>/<session>/subagents/workflows/wf_<id>/*.jsonl

A wf_<id>/ directory whose newest .jsonl was written under ~5 minutes ago is a live run. Note that a quiet agent is usually mid-write rather than dead, so a single sample is not enough; two samples 60 to 90 seconds apart, checking whether the file is still growing, is reliable.

View original on GitHub ↗