[BUG] CLAUDE.md symlinked to AGENTS.md loads both files, duplicating content in context

Status Open
Reported on v2.1.300
Maintainer reply None cached
Activity 0 comments · opened Oct 15, 2026

Description

When ~/.claude/CLAUDE.md is a symlink to ~/AGENTS.md, Claude Code loads both files' contents into the system prompt as two separate instruction blocks instead of deduplicating them. The content is injected twice, verbatim, wasting context tokens.

Environment

  • Claude Code 2.1.300 (macOS, Darwin 25.6.0, arm64)
  • No CLAUDE_CONFIG_DIR override (default ~/.claude)

Steps to reproduce

  1. ln -s AGENTS.md ~/.claude/CLAUDE.md so that ~/.claude/CLAUDE.md -> ../AGENTS.md (confirmed with ls -la: lrwxr-xr-x ... /Users/x/.claude/CLAUDE.md -> ../AGENTS.md).
  2. ~/AGENTS.md is a real file with project/global instructions.
  3. Start a session with cwd somewhere under $HOME (e.g. ~/tmp, not itself a git repo).
  4. Inspect the system prompt / first system-reminder block.

Result

The system prompt contains the full content of the file twice, under two different labels:

Contents of /Users/x/.claude/CLAUDE.md (user's private global instructions for all projects):
<...full content...>

Contents of /Users/x/AGENTS.md (project instructions, checked into the codebase):
<...identical full content...>

Both paths resolve (via realpath) to the same inode — ~/.claude/CLAUDE.md is only a symlink — but the loader treats them as two independent sources: one found via the fixed global-config path, the other via ancestor-directory traversal looking for the nearest AGENTS.md. Neither loader resolves symlinks/realpaths before comparing against files already loaded in the session, so no dedup happens.

Expected

The loader should resolve symlinks (or compare by realpath/inode) before adding a file's content to the prompt, and skip a file whose resolved path is already loaded under another label — consistent with how issue #94463 describes the session_start loader already doing this correctly for literal CLAUDE.md-vs-CLAUDE.md collisions. This case is a different loader pair (global ~/.claude/CLAUDE.md vs ancestor-directory AGENTS.md) but the same missing-realpath-dedup root cause.

Related

  • #94463 — same root cause category (path-string comparison instead of realpath comparison for dedup), different loader pair (nested_traversal vs session_start for CLAUDE.md).
  • #96466 / #78977 / #31005 / #34235 / #62371 / #6235 — various requests around native AGENTS.md support; this issue assumes the current behavior of loading both CLAUDE.md and AGENTS.md independently is intended, and reports only the dedup failure when one is a symlink to the other.

View original on GitHub ↗