CLAUDE_CODE_TASK_LIST_ID set via .claude/settings.json is silently shared across ALL worktrees of a repo, with no per-worktree opt-out, and cross-worktree sync appears non-real-time

Status Open
Reported on v2.1.212
Maintainer reply None cached
Activity 1 comment · opened Jul 18, 2026

Summary

Since v2.1.63, project config (.claude/settings.json, CLAUDE.md, skills,
custom agents) is deliberately shared across every git worktree of the same
repository — the settings file lives at the git-common-dir-resolved project
root, so any worktree session reads the same one. That's the right behavior
for hooks/skills/conventions. But CLAUDE_CODE_TASK_LIST_ID rides along as
an ordinary env entry in that same file, and task-list scoping is a
different kind of concern than config sharing: worktrees are specifically
used to isolate concurrent, unrelated work, and a persistent task list is
exactly the kind of state you'd want isolated per feature/worktree, not
pooled repo-wide.

The result: setting CLAUDE_CODE_TASK_LIST_ID (directly, or via a tool that
suggests it — see below) to get task persistence across sessions has the
side effect of making every worktree of the project — including ones for
completely unrelated, concurrently-running features — share one task list,
permanently, with no way to scope it narrower short of unsetting the
variable for the whole project.

How this was hit

A settings-scaffolding tool (a Claude Code plugin, not part of Claude Code
itself) prompts: *"No persistent Task List ID configured. For a project this
size, tasks won't survive across sessions. Add one?"* and on "yes" writes
{"env": {"CLAUDE_CODE_TASK_LIST_ID": "<repo-name>"}} into
.claude/settings.json. The prompt frames this purely as "persistence across
sessions" — it does not disclose that the same change also collapses task
isolation across every worktree of the repo, forever, with no per-worktree
override available. A user reasonably expecting only persistence got
persistence + forced repo-wide pooling as an undisclosed bundle.

In practice: two completely unrelated features were being developed
concurrently in two different worktrees of the same repo (one an in-progress
implementation, one a separate planning/spec-writing session). A third
session, working directly in the primary checkout on a small, unrelated bug
fix, started seeing the other worktree's task list (status, in-progress
markers, everything) in its own TaskList tool results and status line —
despite never having created or touched any of those tasks. Confirmed via a
direct TaskList tool call (not just passive status-line display) that this
is real shared backing state, not a rendering artifact.

Additional symptom: cross-worktree sync does not appear to be real-time

Separately, and possibly related: a user running multiple worktree-based
sessions against the same shared task list reports the status line
appearing to "stick" on one task for an extended period, then several tasks'
statuses changing at once in a burst — rather than updating incrementally as
they actually happen. This is consistent with the shared list being read
lazily (on next poll/render/tool-call) rather than genuinely pushed live to
every session watching it, and that lazy-catch-up behavior being more
noticeable specifically when the writer and reader sessions are in
different worktrees rather than the same working directory (where
filesystem-level watching may behave differently than across a linked
worktree's separate directory). This wasn't independently instrumented/
reproduced with certainty — noting it as a related observation from the same
incident, not a confirmed root cause.

Expected behavior

Either:

  • CLAUDE_CODE_TASK_LIST_ID (and task-list state generally) should default

to worktree-scoped, with an explicit, separate mechanism to opt into
repo-wide sharing when that's actually wanted (the inverse of current
behavior) — since config/hooks/skills sharing and task-coordination
sharing are different concerns with different natural defaults; or

  • At minimum, some documented way to set a per-worktree override (e.g. a

magic value like ${worktree} that resolves to the current worktree's
directory/branch name at session start, distinct from a literal string)
so a project can have persistence and per-worktree isolation
simultaneously, rather than being forced to choose one or the other
project-wide.

  • If genuine cross-worktree sharing is intended and working as designed, the

broadcast/sync mechanism should be verified to actually propagate updates
promptly across worktree boundaries, not just within a single working
directory.

Actual behavior

  • One .claude/settings.json (shared by design across all worktrees of a

repo, confirmed since v2.1.63) is the only place to set
CLAUDE_CODE_TASK_LIST_ID, so any value set there is necessarily
repo-wide — there is no worktree-relative interpolation available.

  • A session with no awareness of, or connection to, another worktree's work

sees that worktree's full task list and live status through its own
TaskList tool calls.

  • Updates from one worktree's session to a shared list appear to surface in

batches on another session's view rather than incrementally in real time.

Environment

  • Claude Code 2.1.212
  • Reproduced via: .claude/settings.json with `{"env":

{"CLAUDE_CODE_TASK_LIST_ID": "<repo-name>"}} at a repo's primary checkout
root, with
.claude/worktrees/<name>` linked worktrees nested underneath,
multiple concurrent sessions across the primary checkout and two different
worktrees.

Related issues

Not a duplicate of any of these as far as I can tell, but closely adjacent —
same general "worktree isolation has surprising gaps" territory:

  • #29083 — subagent file paths resolve to the main tree instead of the

active worktree (file-edit isolation, not task-list/config sharing)

  • #27343 — CLAUDE_PROJECT_DIR resolves to the main repo inside a worktree
  • #34437 — "Worktrees should share the same project directory as the main

repo" (argues the opposite direction — that config sharing is desirable;
this issue isn't disputing that for config/hooks/skills, only for
task-list coordination state specifically)

  • #4963 — Feature Request: Integrated Parallel Task Management and Worktree

Orchestration (closed, not planned; proposed a different UX — /tasks,
/fork — doesn't address CLAUDE_CODE_TASK_LIST_ID scoping specifically)

None of the above, nor anything else found searching the changelog/issue
tracker, specifically addresses CLAUDE_CODE_TASK_LIST_ID scoping across
worktrees, or the sync-latency observation above.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗