[BUG] Background agent and task IDs stop resolving across a session-identity boundary (transcripts and outputs remain on disk)

Status Open
Maintainer reply None cached
Activity 7 comments · opened Jul 15, 2026

Feedback ticket — Background agent transcripts become unresumable, forcing full-context respawns (token burn)

Date filed: 2026-07-15
Reporter: Shawna Cason (Claude Max subscriber)
Product: Claude Code CLI v2.1.209 · model Fable 5 (claude-fable-5) main loop, kaleido custom subagents · macOS (Darwin 25.5.0)
Severity: Medium — repeated forced re-initialization of background agents multiplies token cost of iterative workflows

---

Summary

During a long iterative design session (a custom kaleido agent running successive design rounds against local HTML/SVG files), background agents that had just completed successfully could not be resumed via SendMessage minutes later:

Agent "<id>" could not be resumed: No transcript found for agent ID: <id>

This happened at least five times in one session (~2026-07-14, session 7f97147b-bc98-4424-a1af-fa3f8a54b415, project dir ~/.claude/projects/-Users-shawnacason/). Each failure forced spawning a fresh agent that had to re-read all project state (design-direction logs, session-state handoffs, 15+ reference images, prior render proofs) before doing any new work — an estimated 30–60k tokens of pure re-initialization per respawn, five-plus times over.

A related delivery bug compounded it: a SendMessage to a running agent returned "Message queued for delivery … at its next tool round", but the agent completed without ever receiving the message; the instruction had to be re-sent to a fresh agent (and in one case the un-received instruction concerned user rulings — three kill decisions — which the completed round then visibly violated, requiring an additional correction round).

Observed sequence (representative)

  1. Agent a3b6355817ef178bb runs ~14 rounds successfully across several hours (resumed repeatedly via SendMessage — resume works).
  2. A completion notification arrives; subagent token counter visible in usage (~450k+ across its lifetime).
  3. Next SendMessage minutes later → No transcript found for agent ID.
  4. New agent spawned; must re-read SESSION_STATE.md, DESIGN_DIRECTION.md, all reference images, prior proofs (the workflow's own handoff discipline makes this survivable, but expensive).
  5. Pattern repeats with the successor agents (ad4fd742…, a0e36471…, a13c6624…, a94043419… — each lost after 1–2 rounds).

Impact

  1. Multiplied token burn: an iterative crit loop that should cost one warm-context increment per round instead pays a full cold-start (state files + image re-reads) on every round where the transcript vanished. Rounds were observed at 130k–450k subagent tokens; a large share of the later rounds' cost is re-initialization, not new work.
  2. Lost instructions: the "queued for delivery" message that never arrived contained user design rulings; the shipped round contradicted them and had to be redone.
  3. Perceived model regression: from the user's seat, this reads as "Claude suddenly burns tokens much faster than a few days ago," even though the proximate cause is harness-side transcript/session lifecycle behavior.

Expected behavior

  • A completed background agent should remain resumable (as documented: "a send resumes it from its transcript") for a reasonable window; silent transcript loss should not occur minutes after completion.
  • If a transcript is evicted/compacted, SendMessage should say so explicitly (and ideally offer the last-known output), rather than a generic not-found.
  • "Message queued for delivery" should be a guarantee or an error — if the agent completes before delivery, the sender should be notified that the message was NOT delivered so instructions aren't silently dropped.

Reproduction shape

  1. Spawn a background custom agent that does heavy tool use (many screenshots/file reads → 150k+ tokens per run).
  2. Let it complete; receive the task notification.
  3. SendMessage to the same agent ID within minutes → observe No transcript found.
  4. Separately: SendMessage while the agent is mid-run and about to finish → observe "queued for delivery" followed by completion without the message ever being processed.

Evidence locations (local)

  • Session ~/.claude/projects/-Users-shawnacason/7f97147b-bc98-4424-a1af-fa3f8a54b415.jsonl (2026-07-14 → 07-15): contains the SendMessage failures verbatim and the respawn chain.
  • Agent output files under /private/tmp/claude-501/-Users-shawnacason/7f97147b-…/tasks/ (per-agent outputs referenced in the session).

Ask

  1. Investigate transcript retention/eviction for completed background agents (correlation with very large subagent transcripts, 150k+ tokens, suspected).
  2. Make SendMessage delivery outcomes truthful: delivered / not-delivered, never silently dropped.
  3. Consider surfacing "this agent's transcript was evicted" in the completion notification so orchestrators can hand off proactively instead of discovering it on the next send.

View original on GitHub ↗

7 Comments

simplysdm · 1 month ago

Related tickets from the same reporter, same week — idle-loop/false-progress claims on both current models: Fable 5 https://github.com/anthropics/claude-code/issues/77727 · Opus 4.8 https://github.com/anthropics/claude-code/issues/77728. Together these three account for the perceived 'sudden token burn increase' on a Max plan: empty progress turns (77727/77728) plus forced cold-start respawns and dropped inter-agent messages (this issue).

simplysdm · 1 month ago

Clarification on evidence: the ~/.claude/projects/...jsonl paths listed are on the reporter's local machine and not accessible to Anthropic. For server-side correlation, use the session UUIDs + UTC timestamps quoted in the report (reporter is a Claude Max subscriber; an in-product /bug report referencing this issue number has also been filed from the same account). Full local transcript excerpts available on request.

SuzieKJJ · 1 month ago

Confirming this from an independent setup, with a precisely-diagnosed reproduction variant that may explain (at least one path to) the symptom.

Environment: Claude Code v2.1.212, macOS (Darwin 25.5.0), Fable 5 main loop, custom Sonnet subagents.

Repro path we hit

  1. Three background subagents running; stopped them via TaskStop (user leaving work, intending to resume later). Stop succeeded, transcripts intact at that point.
  2. Laptop lid closed. ~2 hours later, lid reopened — same Claude Code app instance, no restart, same conversation window.
  3. User sent a message to continue; the conversation resumed seamlessly on the surface, but the harness continued it under a new internal session ID. Filesystem evidence from /private/tmp/claude-<uid>/<project>/:
  • old session dir c64078ec-… — created Jul 13 11:24 (the original session, 5 days of work)
  • new session dir 4c4a1012-… — created Jul 17 19:38, i.e. the exact moment the user re-engaged
  • both sessions' conversation .jsonl transcripts exist side by side in ~/.claude/projects/<project>/
  1. SendMessage to each of the three stopped agents → Agent "<id>" could not be resumed: No transcript found for agent ID: <id>while the previous session's task output files and transcripts still exist on disk under the old session directory.

Contrast data point (supports a session-keyed-lookup hypothesis)

Three days earlier in the same conversation, the user performed a manual rewind/compaction (double-Esc rewind picker). That preserved the session ID — and resuming a previously-idle background agent via SendMessage worked fine afterwards ("had no active task; resumed from transcript"). So: manual compaction (same session ID) → resume OK; automatic continuation minting a new session ID → resume fails. This suggests the resume lookup resolves agent transcripts only within the current session's registry and does not traverse the continuation chain to predecessor sessions, even though the harness knows the linkage and the transcript files are still present.

Impact

Same as OP: forced full-context respawns. We were lucky (agents were stopped in an analysis phase, deliverables already committed), but the failure is silent and unpredictable from the user's perspective — nothing at TaskStop time warns that a stopped agent may become unresumable if the conversation crosses a session boundary.

Suggestions

  1. When resolving an agent ID for resume, fall back to predecessor sessions in the continuation chain (the transcripts are on disk; only the lookup fails).
  2. Failing that, have TaskStop/stop-notifications state the limitation explicitly, so users can decide to let agents finish instead of pausing.
  3. Document the boundary: manual rewind preserves resumability; automatic session continuation does not.

Happy to provide the full directory listings/timestamps if useful.

SuzieKJJ · 1 month ago

Addendum with corrections from the affected user's observations:

  1. Context usage was under 50% at the time the session identity changed — well below any compaction threshold. And the Claude Code UI showed no compaction/summarization activity at any point (the user was watching for it; the UI normally surfaces this). So please disregard any implied "continued because context ran out" mechanism in my previous comment — the cause of the session-identity change is unknown to us; what we can evidence is only: (a) the identity changed at the moment the user re-engaged after laptop sleep, (b) prior transcripts remain on disk, (c) agent resume lookup fails across the boundary.
  1. New occurrence since: after a machine crash and claude --resume, the same conversation is now on its third session directory, and the previous session's background agents were again unresumable. The "resume lookup doesn't traverse the session chain" behavior is consistent across both boundary types.

Combined, this looks less like an inherent design trade-off and more like a lookup bug: the session chain is known to the harness, the transcripts exist, only the resolution fails.

simplysdm · 1 month ago

Update from the original reporter, plus a possible reframing.

Not reproducing on v2.1.220 in a session with no session-identity boundary. Today I resumed already-completed background agents four times via SendMessage, spread across roughly two hours, including sends more than an hour after the agent finished. All four returned had no active task; resumed from transcript in the background. Same machine as the original report, macOS Darwin 25.5.0, Opus 5 main loop with Fable 5 subagents.

The distinguishing detail: this session never crossed a session-identity boundary. No sleep, no fork, no restart.

That lines up with the corroborating reports rather than contradicting them, and I think it points at a reframing of this issue.

The transcript is not being lost. The lookup is resolving against the wrong session directory. Every independent report describes the transcript still existing on disk while the resume lookup fails, and each names a different boundary crossing as the trigger:

  • @SuzieKJJ above: laptop sleep, then re-engagement under a new internal session identity.
  • #79764: background-session fork, with the transcript explicitly present in the pre-fork session dir.
  • #78135: intermittent unresolvability right after session start.
  • #65216: worktree relocation.

Four different triggers, one shared shape: agent-to-session binding is captured at spawn, and something rebinds the session underneath it without remapping or re-resolving the agent lookup.

If that framing is right, the fix is in resolution rather than retention, and this issue's current title is misleading enough to be worth changing. Happy to retitle if a maintainer prefers, or to fold it into whichever of the above is the better home.

Original report stands as filed; I am not closing it, since the trigger I originally hit is not one I can rule out from a single clean session.

SuzieKJJ · 1 month ago

Adding a fifth boundary variant supporting @simplysdm's resolution-not-retention framing: context-compaction continuation, with no sleep, restart, fork, or worktree move involved.

Environment: Claude Code v2.1.220, macOS Darwin 25.5.0, Fable 5 main loop, custom Sonnet subagent (same setup as my Jul 17 report; same machine, later session).

Timeline (2026-07-28, UTC+8):

  1. Background subagent dispatched; it completed normally (its git commits exist in a worktree, and its task .output file exists on disk — retention is fine).
  2. User ran a context compaction and continued in the same conversation window, same app instance — no lid close, no restart.
  3. After the compaction boundary, in the continued conversation:
  • TaskList returned No tasks found (there had been multiple tasks, including a still-running bash task that kept working and later delivered its completion notification — so some plumbing survives the boundary);
  • TaskOutput for the completed subagent's task ID returned No task found with ID: — the spawn-time ID was no longer resolvable.
  1. The completion notification for that subagent was delivered in the first post-compaction turn, and it explicitly instructed reading the output file — which the ID lookup then couldn't resolve. The agent's transcript and work products were intact on disk throughout; we recovered by reading the work products (git log in the worktree) instead of the task API.

Matches the shared shape exactly: artifacts present on disk, spawn-time binding unresolvable after a session-identity-ish boundary — here the boundary being compaction-continuation rather than sleep/fork/relocation. Notably the notification channel crossed the boundary fine while the lookup channel didn't, which may narrow where the rebinding happens.

simplysdm · 1 month ago

Retitled, and here is why — plus a consolidated view for whoever triages this

Old title: Background agent transcripts become unresumable (No transcript found), forcing full-context respawns
New title: Background agent and task IDs stop resolving across a session-identity boundary (transcripts and outputs remain on disk)

I filed this as a retention bug. Three independent reproductions later, retention is not the problem — the transcripts and output files are on disk every single time. What fails is resolving a spawn-time ID after the session identity changes. The old title sent triagers looking for data loss that never happens, so I have changed it to describe what the evidence actually shows.

Credit where it is due: that reframing is @SuzieKJJ's, from independent reproductions on a different machine and setup. They also isolated the distinguishing variable and proposed the fix, and corrected their own first hypothesis when the evidence did not support it. Thank you — this ticket is considerably more actionable than what I filed.

The shared shape, stated once

  1. A background agent or task is spawned and does real work.
  2. The conversation crosses a session-identity boundary — the harness continues under a new internal session ID.
  3. Afterwards, the spawn-time ID no longer resolves: SendMessageNo transcript found for agent ID, TaskListNo tasks found, TaskOutputNo task found with ID.
  4. The artifacts are still there. Transcripts under ~/.claude/projects/<project>/, task outputs under /private/tmp/claude-<uid>/<project>/, git commits in worktrees. Recovery is possible by reading files directly; it is the API lookup that fails.

Boundary variants evidenced in this thread

| # | Boundary | Version | Reporter | Symptom surface |
|---|---|---|---|---|
| 1 | Laptop sleep / lid close, same app instance, no restart | v2.1.212 | @SuzieKJJ | SendMessage → No transcript found |
| 2 | Machine crash + claude --resume (third session dir) | v2.1.212 | @SuzieKJJ | SendMessage → No transcript found |
| 3 | Context-compaction continuation, same window, no sleep or restart | v2.1.220 | @SuzieKJJ | TaskList → No tasks found; TaskOutput → No task found with ID |

@SuzieKJJ has also referenced fork and worktree-move boundaries; those are not detailed in this thread, so I have left them out of the table rather than characterize them second-hand.

The two controls that make this a lookup bug rather than a lifecycle trade-off

  • Manual rewind preserves the session ID → resume works. Automatic continuation mints a new ID → resume fails. Same conversation, same machine, same agents. (@SuzieKJJ, Jul 17)
  • No boundary → no failure. On v2.1.220 I resumed four already-completed background agents over roughly two hours, including sends more than an hour after completion. All four returned had no active task; resumed from transcript in the background. That session never crossed a boundary. (Jul 28)

Two further narrowing details, both from variant 3: a still-running bash task kept working and delivered its completion notification across the boundary, and the subagent's own completion notification arrived in the first post-compaction turn and instructed reading an output file whose ID the API could no longer resolve. So the notification channel survives the boundary while the lookup channel does not — which should localize where the rebinding happens.

What changed about my original report

The failures I originally described happened minutes after completion, apparently within one session, on v2.1.209. I cannot reproduce that on v2.1.220 (the Jul 28 control above). Either it was fixed, or my session crossed a boundary I did not observe at the time. I am not asking for work on the v2.1.209 behavior; I am asking for the boundary case, which is reproducible today.

⚠️ A second, separate defect in my original report that this retitle does not cover

The original body also reports SendMessage returning "Message queued for delivery … at its next tool round" to a running agent, which then completed without ever receiving it. In that instance the dropped message carried user decisions, and the completed round visibly contradicted them.

That is a delivery-acknowledgement bug, not an ID-resolution one, and it is unaffected by everything above. Flagging it here so the retitle does not bury it. Happy to split it into its own issue if a maintainer prefers — say the word and I will file it and link back.

Ask

  1. When resolving an agent or task ID, fall back through the session continuation chain. The harness knows the linkage and the files are present; only the resolution fails.
  2. If that is not feasible, say so at the boundary rather than at the next send, so an orchestrator can hand off proactively instead of discovering it mid-task.
  3. Make SendMessage delivery outcomes truthful: delivered or not-delivered, never silently dropped.