ruvnet/ruflo · error · Error

duplicate repository path: ${path}

Error message

duplicate repository path: ${path}

What it means

assertNoPathCollisions() builds the sorted list of tracked plus untracked paths from `git ls-files` and refuses the capture when the exact same path string appears twice. Git's index should never emit a duplicate, so this error almost always indicates a corrupted index or a modified/wrapped git that returns repeated entries.

Source

Thrown at v3/@claude-flow/codex/src/harness/repository-state.ts:216

  assertUnicodeScalarString(path);
  if (path.includes('\\')) throw new Error(`ambiguous repository path separator: ${path}`);
  const normalized = path.normalize('NFC');
  if (
    normalized.length === 0
    || isAbsolute(normalized)
    || normalized.startsWith('-')
    || normalized.split('/').some((part) => part === '' || part === '.' || part === '..')
  ) {
    throw new Error(`unsafe repository-relative path: ${path}`);
  }
  return normalized;
}

function assertNoPathCollisions(paths: readonly string[]): void {
  const exact = new Set<string>();
  const folded = new Map<string, string>();
  for (const path of paths) {
    if (exact.has(path)) throw new Error(`duplicate repository path: ${path}`);
    exact.add(path);
    const key = portableCaseFold(path);
    const prior = folded.get(key);
    if (prior !== undefined && prior !== path) {
      throw new Error(`case-fold repository path collision: ${prior} and ${path}`);
    }
    folded.set(key, path);
  }
}

function repositoryPaths(repoRoot: string, includeUntracked: boolean): readonly string[] {
  const tracked = splitNul(gitBuffer(repoRoot, ['ls-files', '-z'])).map(decodeGitPath);
  const untracked = includeUntracked
    ? splitNul(gitBuffer(repoRoot, ['ls-files', '--others', '--exclude-standard', '-z'])).map(decodeGitPath)
    : [];
  const paths = [...tracked, ...untracked].sort(codeUnitCompare);
  assertNoPathCollisions(paths);
  return paths;

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Run `git ls-files | sort | uniq -d` to identify the duplicated path
  2. Rebuild the index: `rm .git/index && git reset` (or `git read-tree HEAD`)
  3. Re-clone the repository if the index keeps corrupting, and remove any git output wrappers/aliases
Defensive patterns

Strategy: validation

Validate before calling

const dupes = paths.filter((p, i) => paths.indexOf(p) !== i);
if (dupes.length) throw new Error(`duplicate paths: ${dupes.join(', ')}`);

Try / catch

try { capture(); } catch (e) { if (/duplicate repository path/.test(String(e))) { rebuildIndex(); } throw e; }

Prevention

When it happens

Trigger: `git ls-files -z` (or `--others`) emitting the same entry twice: broken .git/index after a crash, third-party git wrappers that concatenate outputs, or manually constructed path lists passed with the same entry twice.

Common situations: A crashed git process left a duplicated index entry; a git alias/wrapper merges results of multiple invocations; case-insensitive filesystems (macOS/Windows) surfaced two index rows that decode to the identical string.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/01c0e767b547c8b5. Report an issue: GitHub.