abhigyanpatwari/GitNexus · error · RegistryNameCollisionError

Registry name "${registryName}" is already used by "${existi

Error message

Registry name "${registryName}" is already used by "${existingPath}".
Pass --name <alias> to register "${requestedPath}" under a different name, or --allow-duplicate-name to allow both paths under the same name (leaves -r <name> ambiguous for these two).

What it means

The global registry (~/.gitnexus/registry.json) keys repos by name. When you register with an explicit --name (or a preserved alias) that is already taken by a different canonical path (canonical-vs-canonical comparison, so /var/foo vs /private/var/foo does NOT collide), registration refuses rather than silently shadowing the existing entry, and points at the two escape hatches: --name <alias> or --allow-duplicate-name.

Source

Thrown at gitnexus/src/storage/repo-manager.ts:851

  // Duplicate-name guard: only fire when the user EXPLICITLY asked for
  // this name (via opts.name or a preserved alias). Unqualified basename
  // and remote-inferred collisions are preserved for backward-compat —
  // they still register, and the user sees the ambiguity at `-r` / `list`
  // resolution time (which is already improved by the disambiguated error
  // messages and list output #829 ships).
  const explicitName = opts?.name !== undefined || isPreservedAlias;
  if (explicitName && !opts?.allowDuplicateName) {
    // Compare canonical-vs-canonical here too so `/var/foo` and
    // `/private/var/foo` (same repo, different form) aren't treated as
    // two colliding paths.
    const collidingEntry = entries.find(
      (e, i) =>
        i !== existingIdx &&
        e.name.toLowerCase() === name.toLowerCase() &&
        canonicalizePath(e.path) !== canonicalInput,
    );
    if (collidingEntry) {
      throw new RegistryNameCollisionError(name, collidingEntry.path, resolved);
    }
  }

  // This run's branch summary (non-primary runs only); hoisted so the
  // re-read-before-write merge below can re-apply it against a fresh snapshot.
  const summary: BranchSummary | null = opts?.branch
    ? {
        branch: opts.branch,
        indexedAt: meta.indexedAt,
        lastCommit: meta.lastCommit,
        stats: meta.stats,
      }
    : null;

  let entry: RegistryEntry;
  if (summary) {
    // Non-primary branch run (#2106): keep the primary's top-level fields and
    // upsert this branch into branches[]. One entry per path is preserved.

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Register under a distinct alias: gitnexus analyze --name app-ci /repoB
  2. If both should share the name (accepting that -r app becomes ambiguous), pass --allow-duplicate-name
  3. Remove the stale entry first: gitnexus remove /repoA, then re-run analyze
  4. List current registrations first so you can see the collision before choosing

Example fix

# before
gitnexus analyze --name app /repoB   # → RegistryNameCollisionError

# after
gitnexus analyze --name app-ci /repoB
# or intentionally keep both under 'app':
gitnexus analyze --name app --allow-duplicate-name /repoB
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
import path from 'node:path';
function nameTakenByOtherPath(name: string, myPath: string): string | null {
  const registry = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.gitnexus', 'registry.json'), 'utf8'));
  const hit = (registry.repos ?? []).find(
    (e: { name: string; path: string }) =>
      e.name.toLowerCase() === name.toLowerCase() &&
      path.resolve(e.path) !== path.resolve(myPath),
  );
  return hit?.path ?? null;
}
if (nameTakenByOtherPath('app', process.cwd())) registryName = 'app-2';

Prevention

When it happens

Trigger: `gitnexus analyze --name app` run in /repoB when 'app' is already registered for the different path /repoA — names match case-insensitively, canonical paths differ.

Common situations: Two clones or forks with the same folder name indexed from different directories (work machine vs CI, upstream vs fork); moving a repo and re-registering under its previous name; teams sharing a machine with same-named checkouts.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20). Data as JSON: /api/errors/603acc6c349bbf94. Report an issue: GitHub.