[BUG] Task list (TaskCreate/TaskList) not restored on --resume/--continue — task-list id resolves to a new runtime id

Status Open
Reported on v2.1.207
Maintainer reply ✓ Yes — bcherny
Activity 4 comments · opened Jul 12, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Claude Code version: 2.1.207
  • Platform: macOS (darwin 25.4.0), zsh
  • Task system: the current TaskCreate/TaskList/TaskUpdate tools (not the deprecated TodoWrite)

Bug description

Tasks created with TaskCreate are not restored when a session is resumed with claude --resume or claude --continue. After resume, TaskList returns an empty list and task numbering restarts from #1, even though the original task files are still present on disk.

Steps to reproduce

  1. Start a session, have Claude create a task via TaskCreate ("Test task").
  2. Observe it persisted on disk: ~/.claude/tasks/session-<8-hex>/1.json.
  3. Exit the session.
  4. claude --resume <that-session> (or claude --continue).
  5. Ask for the task list.

Expected: the task list from the resumed session is visible ("Test task" present).

Actual: the task list is empty; a newly created task lands in a different directory and gets id #1 again.

Diagnosis

Task lists are stored per list-id under ~/.claude/tasks/<list-id>/N.json. On resume, the conversation transcript correctly continues in the same ~/.claude/projects/<project>/<session-id>.jsonl, but the task-list id resolves to a new runtime id, so the session gets a fresh empty directory:

  • Original session 9201ae0c-… wrote tasks to ~/.claude/tasks/session-9201ae0c/.
  • After --resume, the same conversation wrote new tasks to ~/.claude/tasks/session-92efd67b/ (verified by creating a marker task and checking which directory received it).
  • The old directory with the original tasks remains on disk, orphaned.

From the minified binary (2.1.207), the list id is resolved roughly as: CLAUDE_CODE_TASK_LIST_ID env var → team name → runtime session id. The env var works as a stable, shareable list id (verified: launching with CLAUDE_CODE_TASK_LIST_ID=test-list routes new tasks to ~/.claude/tasks/test-list/), but it is undocumented; the default session-derived fallback is what breaks resume continuity.

Expected behavior

Resuming a session should reattach the task list the session was using before exit (the harness even nudges the model about "existing tasks", which makes the silent reset more confusing). Alternatively/additionally, documenting CLAUDE_CODE_TASK_LIST_ID would give users a supported way to keep a task list across sessions.

View original on GitHub ↗

3 Comments

oskar-gm · 1 month ago

Same on 2.1.215 (Windows) — one more piece on the "team name" branch of that resolution chain.

With CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1, the interactive TUI creates an implicit team at startup even if you never spawn a teammate: ~/.claude/teams/session-<8hex>/config.json with a single team-lead member. That team's name (session-<8hex>) becomes the task-list id — which is why the taskdir is session-<8hex> rather than the full session id. Headless (-p) doesn't create the team.

So there's a mitigation that, unlike CLAUDE_CODE_TASK_LIST_ID, doesn't force one shared list across every session: unset the flag. No implicit team → the list-id falls back to the session id → resume reattaches.

Verified on 2.1.215:

  • TUI + flag: ~/.claude/teams/session-<8hex>/config.json present with a lone team-lead; the taskdir is named identically.
  • Headless, full-UUID taskdir (no team): create a task, --resume, the task is still there and the session id is unchanged.

I couldn't script the TUI path end-to-end, so I'm flagging the implicit team as the trigger rather than proving the internal code path — but unsetting the flag is what restores persistence here. The naming switch to session-<8hex> landed in 2.1.178, which lines up with when resume started dropping tasks for team-flag users.

scapeshift-ojones · 1 month ago

Confirming this on 2.1.216 (macOS, darwin 24.5.0) — still reproducible, and the on-disk evidence matches the diagnosis in the OP exactly.

Repro from today:

  1. Session c46f522e… created tasks #1–3 via TaskCreate; they persisted to ~/.claude/tasks/session-c46f522e/{1,2,3}.json (verified present with correct subjects/status after the fact).
  2. Resumed the session.
  3. TaskList in the resumed session → "No tasks found", while the three JSON files are still intact on disk under the original session-c46f522e list-id.

So the transcript resumes under the same session, but the task-list id resolves to a fresh runtime id and the tool reads an empty directory — data intact, list invisible. Same root cause as #80871 (there surfacing as Task not found from TaskUpdate on pre-resume IDs).

bcherny collaborator · 15 days ago

Reproduced on v2.1.233 (macOS), with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 set (the per-session team is what routes the task list to a session-<8hex> directory).

Steps:

  1. CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 claude in an empty project dir. (On newer models the task tools are off by default, so I also set CLAUDE_CODE_ENABLE_TODO_TOOLS=1.)
  2. Prompt: "Use the TaskCreate tool to create one task with subject 'Test task'." → task panel shows 1 tasks (0 done, 1 open) ◻ Test task; on disk ~/.claude/tasks/session-0adfd7b2/1.json (session id 0adfd7b2-…).
  3. /exit, then claude --resume 0adfd7b2-… with the same env vars.
  4. Prompt: "Use the TaskList tool and reply with exactly what it returns."

Observed: No tasks found, and the task panel is gone. The transcript resumed correctly, but a new ~/.claude/teams/session-9df2fea7/ and a new empty ~/.claude/tasks/session-9df2fea7/ were created; the original session-0adfd7b2/1.json is left orphaned on disk.

Expected: the resumed session reattaches to its previous task list (Test task visible in TaskList and the task panel).

Assessment: This is a genuine bug. The agent teams docs say the task list directory persists so that resumed sessions keep their tasks (https://code.claude.com/docs/en/agent-teams#architecture), but on --resume the session-scoped team name is derived from the fresh startup session id before the resumed session id is applied, so the resumed session gets a new empty task list. This is a regression from around v2.1.178, when the implicit per-session team was introduced; before that, tasks were keyed directly on the (resumed) session id and were found again. It only affects sessions with agent teams enabled.

🤖 Generated with Claude Code

Showing cached comments. Read the full discussion on GitHub ↗