Skip to content

Bug: isProjectRoot() doesn't detect subdirectories within git repos, causing CLAUDE.md files in all subfolders #793

@alexrodriguezintegrityxd

Description

Bug Summary

The isProjectRoot() function in src/utils/claude-md-utils.ts only checks if a folder directly contains a .git directory. It does NOT check if the folder is inside a git repository. This causes CLAUDE.md files to be created in all subdirectories of git repos.

Root Cause

File: src/utils/claude-md-utils.ts:241-243

function isProjectRoot(folderPath: string): boolean {
  const gitPath = path.join(folderPath, '.git');
  return existsSync(gitPath);  // ❌ Only checks if THIS folder contains .git
}

Problem Scenario

Given a directory structure:

/Users/user/.claude/                  ← has .git directory
├── .git/                             ← git repo root
├── commands/
│   └── dev/
│       └── workflow/                 ← NO .git in this folder

Current behavior:

  • /Users/user/.claude/isProjectRoot() returns true → CLAUDE.md skipped ✓
  • /Users/user/.claude/commands/dev/workflow/isProjectRoot() returns falseCLAUDE.md created

Expected behavior:

  • Both should skip CLAUDE.md generation because both are inside the git repo

Impact

This causes:

  1. Repository pollution (Bug: 50-120+ CLAUDE.md files created per session causing repository pollution #778): 50-120+ CLAUDE.md files created per session in subdirectories
  2. Git corruption (Bug: CLAUDE.md files created inside .git directory causing git pull failures #734): CLAUDE.md files created inside .git/refs/, .git/logs/, breaking git operations
  3. Python package shadowing (CLAUDE.md file creation causes Python package shadowing when working in subdirectories #697): CLAUDE.md in subdirectories interferes with package discovery
  4. Duplicate nested files (Bug: Observation system creates CLAUDE.md files in project subdirectories and duplicate nested directories #641): Nested directory structures accumulate CLAUDE.md files

Related issues: #778, #734, #697, #641, #635, #632, #758

Solution

Walk up parent directories to check if any ancestor contains .git:

function isInsideGitRepo(folderPath: string): boolean {
  let current = folderPath;
  const root = path.parse(current).root;
  
  while (current !== root) {
    if (existsSync(path.join(current, '.git'))) {
      return true;  // Found .git in ancestor
    }
    current = path.dirname(current);
  }
  return false;
}

Then update line 287 to use isInsideGitRepo instead of isProjectRoot:

if (isInsideGitRepo(folderPath)) {
  logger.debug('FOLDER_INDEX', 'Skipping folder inside git repo', { folderPath });
  continue;
}

Environment

  • Affected versions: 9.0.1+ (all versions with folder CLAUDE.md feature)
  • Platforms: All (macOS, Linux, Windows)
  • Claude-mem: Latest
  • Root cause: Design flaw in path validation logic

Test Cases

After fix, these should all skip CLAUDE.md generation:

  • ✓ Folder with .git directly inside
  • ✓ Folder inside git repo (multiple levels deep)
  • ✓ Folders inside .git/refs/, .git/logs/ (edge case)
  • ✗ Folder outside any git repo (should generate CLAUDE.md if otherwise valid)

Priority

High - Causes data corruption (git repo pollution, git command failures)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:criticalCritical priority

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions