claude-code - 💡(How to fix) Fix Duplicate .claude/rules loading in worktrees nested inside .claude/ [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#46222Fetched 2026-04-11 06:25:56
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×3commented ×1

When using worktrees created inside .claude/worktrees/, rules from .claude/rules/ are loaded twice — once from the worktree's own copy and once from the parent repo's .claude/rules/ (discovered via ancestor directory traversal).

Root Cause

Rules are loaded twice because:

  • The worktree is physically located at <repo>/.claude/worktrees/<name>/
  • The worktree has its own .claude/rules/ (checked into git)
  • Walking up the filesystem from the worktree also finds <repo>/.claude/rules/
  • Both are loaded, resulting in duplicate context and wasted tokens

Code Example

Loaded ../../rules/pagination.md
Loaded ../../rules/security.md
Loaded ../../rules/viewsets.md
Loaded .claude/rules/pagination.md
Loaded .claude/rules/security.md
Loaded .claude/rules/viewsets.md
RAW_BUFFERClick to expand / collapse

Summary

When using worktrees created inside .claude/worktrees/, rules from .claude/rules/ are loaded twice — once from the worktree's own copy and once from the parent repo's .claude/rules/ (discovered via ancestor directory traversal).

Steps to reproduce

  1. Have a project with .claude/rules/ containing rule files
  2. Enter a worktree (created at .claude/worktrees/<name>/)
  3. Observe that rules are loaded twice:
Loaded ../../rules/pagination.md
Loaded ../../rules/security.md
Loaded ../../rules/viewsets.md
Loaded .claude/rules/pagination.md
Loaded .claude/rules/security.md
Loaded .claude/rules/viewsets.md

Expected behavior

Each rule file should be loaded only once. When operating inside a worktree, the rule discovery should deduplicate rules that resolve to the same file content/origin, or skip ancestor .claude/rules/ directories that belong to the parent repo.

Actual behavior

Rules are loaded twice because:

  • The worktree is physically located at <repo>/.claude/worktrees/<name>/
  • The worktree has its own .claude/rules/ (checked into git)
  • Walking up the filesystem from the worktree also finds <repo>/.claude/rules/
  • Both are loaded, resulting in duplicate context and wasted tokens

Impact

  • Duplicate context consumes tokens unnecessarily (each rule file is sent twice)
  • With many rule files, this compounds significantly

Suggested fix

During rule discovery, if the current working directory is a worktree nested inside another repo's .claude/, skip ancestor .claude/rules/ directories that belong to the parent repo.

extent analysis

TL;DR

Modify the rule discovery logic to skip ancestor .claude/rules/ directories that belong to the parent repo when operating inside a worktree.

Guidance

  • Identify if the current working directory is a worktree by checking if it's located inside another repo's .claude/ directory.
  • If it's a worktree, modify the rule discovery to exclude ancestor .claude/rules/ directories that are not part of the worktree's own repository.
  • Consider implementing a deduplication mechanism to ensure each rule file is loaded only once, even if it's present in both the worktree and parent repo.
  • Verify the fix by checking the loaded rules and ensuring that each rule file is only loaded once.

Example

import os

def is_worktree(path):
    # Check if the path is inside another repo's .claude/ directory
    while True:
        parent_dir = os.path.dirname(path)
        if os.path.exists(os.path.join(parent_dir, '.claude')):
            return True
        if parent_dir == path:
            break
        path = parent_dir
    return False

def load_rules(path):
    rules = []
    if is_worktree(path):
        # Skip ancestor .claude/rules/ directories that belong to the parent repo
        for root, dirs, files in os.walk(path):
            if os.path.basename(root) == 'rules' and root.startswith(os.path.join(path, '.claude')):
                for file in files:
                    rules.append(os.path.join(root, file))
    else:
        # Load rules as before
        pass
    return rules

Notes

The provided example is a simplified illustration and may need to be adapted to the actual implementation. The is_worktree function checks if the current directory is a worktree by traversing up the directory tree and checking for the presence of a .claude directory.

Recommendation

Apply a workaround by modifying the rule discovery logic to skip ancestor .claude/rules/ directories that belong to the parent repo when operating inside a worktree, as this approach directly addresses the identified issue and prevents duplicate rule loading.

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…

FAQ

Expected behavior

Each rule file should be loaded only once. When operating inside a worktree, the rule discovery should deduplicate rules that resolve to the same file content/origin, or skip ancestor .claude/rules/ directories that belong to the parent repo.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING