[Bug] Workflow: died-and-respawned agent's result is journaled under a different key than its 'started' entry, permanently breaking resumeFromRunId
Version: 2.1.207 (Claude Code), Linux
Area: Workflow tool / journal / resume
What happened
During a Workflow run, one agent() call's subagent died mid-task and the harness respawned it; the run continued normally (the script received the respawn's result and the orchestration advanced).
The run's journal.jsonl now contains:
startedunder keyv2:f152a0dc8f3…(original agent) with no matchingresultunder that key, and- an orphan
resultunder keyv2:bed24e2e16e…(the respawned agent's id) with no matchingstarted.
On Workflow({scriptPath, resumeFromRunId}) with a byte-identical script and args:
- the first call (bootstrap) returned from cache — proving the journal was found and args matched;
- the died-and-respawned call re-keyed to the same
v2:f152a0dc8f3…as the originalstarted— proving prompt/opts identity; - no cached result was found under that key, so the call and everything after it re-ran live — in our case 5 completed build units plus a full review round were silently re-executed.
Expected
The respawned agent's result should be journaled under the originating call's key, so started/result key pairing holds and resume replays the completed prefix — per the documented contract "Same script + same args → 100% cache hit."
Impact
Any workflow run in which a subagent died and was retried mid-call becomes permanently unresumable past that point. The failure is silent: resume looks like it "just started the whole run from the beginning." Diagnosis requires manually pairing started/result keys in journal.jsonl.
Repro sketch
- Run a multi-step workflow; have one subagent die on a terminal-then-retried error mid-call (e.g. transient API failure), letting the harness respawn it and the run complete or pause later.
- Resume with
resumeFromRunIdand unchanged script/args. - Observe cache hits up to the died agent's call, then a full live re-run from that call onward; observe the started/result key mismatch in
journal.jsonl.
Not a duplicate of
- #67488 — cache misses from non-deterministic prompt construction (there the recomputed key differs; here it provably matches, the journal side is what's wrong).
- #65796 — journal directory not resolved after compaction (here the journal was found and partially hit).
Aside
A paused workflow task rejects TaskStop with "not running (status: paused)", while the resume documentation says to stop the prior run before resuming — the two contradict for paused runs.
🤖 Filed with Claude Code after diagnosing the journal of an affected run.