[BUG] Task store files deleted without any Task tool call, ~5s after a teammate completes the highest-numbered task (2.1.234–2.1.237)

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

What's Wrong?

Task JSON files under ~/.claude/tasks/session-<short8>/ are deleted by Claude Code itself with no corresponding Task tool call — no TaskUpdate status:deleted anywhere in any transcript in the relevant windows. Observed four times, in two fingerprints, with a consistent trigger: a teammate agent completing the highest-numbered task in a shared store, ~5.1s before the loss.

The last occurrence happened on demand while investigating this issue, which is what turns the forensic account below into a near-minimal reproduction.

The trigger, four occurrences

| # | date | id completed | delta to loss | outcome | .highwatermark after | version |
|---|---|---|---|---|---|---|
| A1 | 2026-08-20 | 12 | 5.11s | whole store emptied | rewritten, content 12 | 2.1.236 lead / 2.1.237 teammate |
| B | 2026-08-20 | 3 | 5.12s | one file removed | untouched (left stale) | 2.1.237 |
| A3 | 2026-08-20 | 6 | 5.14s | whole store emptied | rewritten, content 6 | 2.1.237 |
| A2 | 2026-08-18 | — | see below | whole store emptied | rewritten, content 3 | 2.1.234 |

In A1, B and A3: the completed task was the highest-numbered task in the store, the completion came from a teammate agent rather than the lead, the tool call succeeded normally, and where the mark is rewritten at all its content is byte-identical to the id just completed. That last detail is consistent with the deletion being performed by code holding the completed task's id, not by a generic sweep. There is no tool call and no shell activity of any kind in any of the 5.1s gaps — every transcript under ~/.claude/projects/ live in those windows was re-scanned, not only the affected sessions.

The delta being ~5.1s across two different outcomes (whole store vs. one file) points at one delayed action on a fixed timer rather than two unrelated defects.

Fingerprint A — full-store wipe

Every <id>.json in the store is unlinked and .highwatermark is rewritten in what appears to be a single operation: directory mtime and .highwatermark mtime are identical to the nanosecond. .lock is left untouched, so this is not a directory removal or a move — something unlinked the files individually and then wrote the mark.

Occurrence A12026-08-20T18:09:15.744Z. The store held 2 tasks (highwatermark 12). At the purge moment the lead session was provably idle: its Stop hook fired ~2 minutes prior, it made no tool calls in the window, and no new Claude process booted (verified against ~/.claude/sessions/*.json). The next interaction with the store, ~30s later, returned "Task not found" / "No tasks found".

Occurrence A3 — the on-demand one, 2026-08-20T19:42:30.648Z. A teammate agent in an affected session completed the store's only (and highest-numbered) task; the store emptied 5.14s later.

Occurrence A2 — 2026-08-18, 16:29:55.948Z, found during the investigation. Same signature (transcript contains 4 TaskCreate calls and zero delete calls, yet the store holds .highwatermark=3 and no json files), but it does not fit the 5s pattern and should not be read as if it did: the nearest preceding completion is 16:28:09.209Z (taskId:2), 1m46s earlier. What does sit adjacent to it is a different event — roughly 10s after the store emptied, at 16:30:05.634Z, the lead session sent a message to a teammate stating that the teammate's previous turn had died on a transient API error. The teardown of that turn is the nearest event to the loss. So there may be a second path into the same outcome, around abnormal teammate/subagent teardown. Stated plainly: this is circumstantial, a single occurrence, and I cannot show a causal link — only that the two events are adjacent and nothing else in the window is.

Fingerprint B — single-file removal with no mark write

A task's json file vanished ~5s after its own TaskUpdate {status:completed} succeeded. .highwatermark was not touched — it was left 2m41s stale, last written by earlier accountable deletions.

Control measurement: an explicit TaskUpdate status:deleted always rewrites .highwatermark in the same nanosecond as the directory change. A removal that leaves the mark stale therefore has no accountable origin.

A1 and B are the same conversation

They are not two independent stores:

  • Store A was the conversation's store until it was emptied at 18:09:15.744Z.
  • After a restart, a new store directory appears under ~/.claude/tasks/ at 18:11:08Z, handed to the same conversation.
  • Store B's .lock is dated 18:14:28.42Z, matching to the millisecond that conversation's first TaskCreate after the restart (18:14:28.400Z).

One conversation lost its task list twice within an hour, in two different shapes — again pointing at a single mechanism.

Ruled out

  • No Task tool_use of any kind in any transcript under ~/.claude/projects/ during the windows.
  • No external tooling: everything on the machine that touches ~/.claude/tasks/ was audited — all of it is read-only or copy-only toward that directory.
  • No cron/systemd timers touch the path.
  • Not compaction: in A1, /compact completed 7.5 minutes before the wipe, and tasks were successfully written after it.
  • Not locking: .lock existed in all affected stores and did not prevent the loss.

What Should Happen?

Task files should only ever be removed by an explicit TaskUpdate status:deleted (or documented lifecycle events). A session's task list should never silently empty while the sessions holding it are idle, and completing a task should never remove any file.

Error Messages/Logs

# Store state after fingerprint A (occurrence A1):
~/.claude/tasks/session-<short8>/
  .highwatermark   content "12"   mtime 18:09:15.744414055Z
  .lock
  (zero *.json files; directory mtime == .highwatermark mtime to the nanosecond)

# Timeline (UTC), occurrence A1:
18:07:09      lead session Stop hook fires (idle from here on)
18:09:10.634  TaskUpdate {taskId:12, status:completed} -> succeeds (last accountable write)
18:09:15.744  all *.json unlinked + .highwatermark rewritten in one operation
18:09:47.12   TaskUpdate #12 -> "Task not found"
18:09:48.97   TaskList -> "No tasks found"

# Timeline (UTC), fingerprint B — the affected session's own next tool call, nothing in between:
19:03:06.4 / 19:03:07.4  .highwatermark created + rewritten by accountable deletions
19:05:43.222  TaskUpdate {taskId:3, status:completed} -> success
19:05:48.337  3.json removed; .highwatermark NOT rewritten (left stale)
19:06:27.529  TaskGet {taskId:3} -> "task not found"

# Timeline (UTC), occurrence A3 (on demand, known actor):
19:33:09.849  6.json written into the store (task created, highest id)
   ...        teammate agent works; store holds exactly this one task
19:42:25.512  TaskUpdate {taskId:6, status:completed} -> success
19:42:30.648  all *.json unlinked + .highwatermark rewritten, one operation (delta 5.14s)
   later      TaskGet {taskId:6} -> "Task not found"

# Store state immediately after A3:
~/.claude/tasks/<store>/
  .highwatermark   content "6"    mtime 19:42:30.648429999
  .lock                           mtime 18:14:28.424914567  (untouched)
  (zero *.json; directory mtime == .highwatermark mtime to the nanosecond)

Steps to Reproduce

This is the shape that has produced the fault three times, including once on demand. I cannot promise it fires every time, but it is a tight target:

  1. Start a session that becomes a team lead and create several tasks.
  2. Spawn a teammate agent that shares the lead's task store.
  3. Have the teammate call TaskUpdate {taskId:<highest id in the store>, status:"completed"}.
  4. Watch ~/.claude/tasks/<store>/ for ~10 seconds — no further tool calls needed.

Expected: the store keeps its task files. Observed: roughly five seconds after the completion, either the whole store is emptied and .highwatermark is rewritten to the just-completed id, or that task's json alone is removed with the mark left untouched.

Detection aid for triage: an accountable delete rewrites .highwatermark with dir-mtime == mark-mtime to the nanosecond; both bug fingerprints violate that invariant (A: mark rewritten with no tool call behind it; B: file removed with mark untouched).

Environment

  • Claude Code Version: 2.1.234 through 2.1.237 — the fault is not confined to one release. A2 ran 2.1.234; at A1 the affected session's own process was on 2.1.236 while the teammate agent that performed the triggering completion was already on 2.1.237, sharing the store across the two; fingerprint B and A3 were 2.1.237 throughout. Versions verified for the acting process from /proc/<pid>/exe rather than from the on-disk binary. The two most recent occurrences, including the on-demand one, are entirely on the current release.
  • Claude Model: Opus/other (multiple models; the lead session in A1 was idle at wipe time)
  • Is this a regression: I don't know — the oldest occurrence found (2.1.234) already shows the signature.
  • Platform: Anthropic API
  • Operating System: Ubuntu-based Linux
  • Terminal: kitty (tmux)

Additional Information

  • All affected stores were team/shared task directories in active use by a lead + teammate sessions (Agent tool teammates).
  • Impact: silent, unrecoverable loss of the session's task list — nothing else on disk links task content to the store once the json files are gone. It is discovered minutes later via a failing task lookup, with no error surfaced at deletion time.
  • Suggested triage angle: whatever runs on task completion — and possibly on abnormal teammate teardown — approximately five seconds after the fact, in a session that shares its task store with teammates.

View original on GitHub ↗