claude-code - 💡(How to fix) Fix Rules files loaded twice when using built-in worktree isolation (.claude/worktrees/) [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#47897Fetched 2026-04-15 06:39:12
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Author
Timeline (top)
labeled ×4commented ×1

When using Claude Code's built-in worktree isolation (e.g., isolation: "worktree" in Agent tool, or EnterWorktree), the same .claude/rules/*.md files are loaded twice into context — once from the worktree's own .claude/rules/ and once from the parent repo's .claude/rules/ (reachable via directory traversal).

Root Cause

Worktrees are created inside .claude/worktrees/<name>/:

repo-root/
  .claude/
    rules/                         ← parent repo's rules (path 1)
    worktrees/
      radiant-conjuring-squirrel/  ← worktree root
        .claude/
          rules/                   ← worktree's own copy (path 2)

Claude Code's rules loader walks up from the working directory looking for .claude/rules/. From the worktree root, it finds:

  1. <worktree>/.claude/rules/*.md — the worktree's checked-out copy
  2. <worktree>/../../rules/*.md — resolves to the parent repo's .claude/rules/ because the worktree lives inside .claude/worktrees/

Both directories contain identical files (same git content), but the loader treats them as separate because the paths differ.

Code Example

L  Loaded ../../rules/services-infrastructure.md
L  Loaded ../../rules/testing.md
L  Loaded ../../rules/performance.md
L  Loaded ../../rules/clean-architecture.md
L  Loaded ../../rules/api-contracts.md
L  Loaded .claude/rules/services-infrastructure.md
L  Loaded .claude/rules/testing.md
L  Loaded .claude/rules/performance.md
L  Loaded .claude/rules/clean-architecture.md
L  Loaded .claude/rules/api-contracts.md

---

repo-root/
  .claude/
    rules/                         ← parent repo's rules (path 1)
    worktrees/
      radiant-conjuring-squirrel/  ← worktree root
        .claude/
          rules/                   ← worktree's own copy (path 2)
RAW_BUFFERClick to expand / collapse

Description

When using Claude Code's built-in worktree isolation (e.g., isolation: "worktree" in Agent tool, or EnterWorktree), the same .claude/rules/*.md files are loaded twice into context — once from the worktree's own .claude/rules/ and once from the parent repo's .claude/rules/ (reachable via directory traversal).

Reproduction

  1. Have a repo with .claude/rules/*.md files (e.g., 5-15 rules files)
  2. Start a Claude Code session that uses worktree isolation (plan mode, or Agent with isolation: "worktree")
  3. Observe the "Loaded" messages — each rules file appears twice:
L  Loaded ../../rules/services-infrastructure.md
L  Loaded ../../rules/testing.md
L  Loaded ../../rules/performance.md
L  Loaded ../../rules/clean-architecture.md
L  Loaded ../../rules/api-contracts.md
L  Loaded .claude/rules/services-infrastructure.md
L  Loaded .claude/rules/testing.md
L  Loaded .claude/rules/performance.md
L  Loaded .claude/rules/clean-architecture.md
L  Loaded .claude/rules/api-contracts.md

Root Cause

Worktrees are created inside .claude/worktrees/<name>/:

repo-root/
  .claude/
    rules/                         ← parent repo's rules (path 1)
    worktrees/
      radiant-conjuring-squirrel/  ← worktree root
        .claude/
          rules/                   ← worktree's own copy (path 2)

Claude Code's rules loader walks up from the working directory looking for .claude/rules/. From the worktree root, it finds:

  1. <worktree>/.claude/rules/*.md — the worktree's checked-out copy
  2. <worktree>/../../rules/*.md — resolves to the parent repo's .claude/rules/ because the worktree lives inside .claude/worktrees/

Both directories contain identical files (same git content), but the loader treats them as separate because the paths differ.

Impact

  • Doubled context window usage for rules. In our case, 5 rules files × ~5-10KB each = ~50-100KB of wasted context per session.
  • For repos with many rules files, this significantly reduces available context for actual work.

Expected Behavior

Each rules file should be loaded exactly once, regardless of worktree placement. Options:

  1. Deduplicate by content hash — skip loading a file if its content matches an already-loaded rules file
  2. Deduplicate by canonical path — resolve symlinks and .. before loading, skip if the canonical path was already loaded
  3. Stop traversal at worktree boundary — don't walk above the worktree root when looking for .claude/ directories

Environment

  • Claude Code CLI (latest)
  • macOS Darwin 24.5.0
  • Git worktrees created by built-in isolation: "worktree" agent parameter

extent analysis

TL;DR

To fix the issue of duplicated rules files loading in Claude Code's worktree isolation, consider implementing a deduplication mechanism, such as loading files by content hash or canonical path.

Guidance

  • Investigate the feasibility of deduplicating by content hash, where the loader skips loading a file if its content matches an already-loaded rules file.
  • Explore deduplicating by canonical path, which involves resolving symlinks and .. before loading and skipping if the canonical path was already loaded.
  • Consider stopping traversal at the worktree boundary to prevent the loader from walking above the worktree root when looking for .claude/ directories.
  • Review the current implementation of the rules loader to understand how it handles file paths and loading logic.

Example

No specific code snippet can be provided without modifying the existing loader implementation. However, a potential approach could involve maintaining a set of loaded file hashes or canonical paths to check against before loading a new file.

Notes

The chosen solution should ensure that each rules file is loaded exactly once, regardless of worktree placement, without introducing unnecessary complexity or performance overhead.

Recommendation

Apply a workaround by deduplicating by content hash, as it seems to be a straightforward approach to skip loading duplicate files based on their content, thus reducing wasted context window usage.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Rules files loaded twice when using built-in worktree isolation (.claude/worktrees/) [1 comments, 2 participants]