{"record":{"id":"603acc6c349bbf94","repo":"abhigyanpatwari/GitNexus","slug":"registry-name-registryname-is-already-used-by","errorCode":null,"errorMessage":"Registry name \"${registryName}\" is already used by \"${existingPath}\".\nPass --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).","messagePattern":"Registry name \"(.+?)\" is already used by \"(.+?)\"\\.\nPass --name <alias> to register \"(.+?)\" under a different name, or --allow-duplicate-name to allow both paths under the same name \\(leaves -r <name> ambiguous for these two\\)\\.","errorType":"exception","errorClass":"RegistryNameCollisionError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/storage/repo-manager.ts","lineNumber":851,"sourceCode":"  // Duplicate-name guard: only fire when the user EXPLICITLY asked for\n  // this name (via opts.name or a preserved alias). Unqualified basename\n  // and remote-inferred collisions are preserved for backward-compat —\n  // they still register, and the user sees the ambiguity at `-r` / `list`\n  // resolution time (which is already improved by the disambiguated error\n  // messages and list output #829 ships).\n  const explicitName = opts?.name !== undefined || isPreservedAlias;\n  if (explicitName && !opts?.allowDuplicateName) {\n    // Compare canonical-vs-canonical here too so `/var/foo` and\n    // `/private/var/foo` (same repo, different form) aren't treated as\n    // two colliding paths.\n    const collidingEntry = entries.find(\n      (e, i) =>\n        i !== existingIdx &&\n        e.name.toLowerCase() === name.toLowerCase() &&\n        canonicalizePath(e.path) !== canonicalInput,\n    );\n    if (collidingEntry) {\n      throw new RegistryNameCollisionError(name, collidingEntry.path, resolved);\n    }\n  }\n\n  // This run's branch summary (non-primary runs only); hoisted so the\n  // re-read-before-write merge below can re-apply it against a fresh snapshot.\n  const summary: BranchSummary | null = opts?.branch\n    ? {\n        branch: opts.branch,\n        indexedAt: meta.indexedAt,\n        lastCommit: meta.lastCommit,\n        stats: meta.stats,\n      }\n    : null;\n\n  let entry: RegistryEntry;\n  if (summary) {\n    // Non-primary branch run (#2106): keep the primary's top-level fields and\n    // upsert this branch into branches[]. One entry per path is preserved.","sourceCodeStart":833,"sourceCodeEnd":869,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/storage/repo-manager.ts#L833-L869","documentation":"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.","triggerScenarios":"`gitnexus analyze --name app` run in /repoB when 'app' is already registered for the different path /repoA — names match case-insensitively, canonical paths differ.","commonSituations":"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.","solutions":["Register under a distinct alias: gitnexus analyze --name app-ci /repoB","If both should share the name (accepting that -r app becomes ambiguous), pass --allow-duplicate-name","Remove the stale entry first: gitnexus remove /repoA, then re-run analyze","List current registrations first so you can see the collision before choosing"],"exampleFix":"# before\ngitnexus analyze --name app /repoB   # → RegistryNameCollisionError\n\n# after\ngitnexus analyze --name app-ci /repoB\n# or intentionally keep both under 'app':\ngitnexus analyze --name app --allow-duplicate-name /repoB","handlingStrategy":"validation","validationCode":"import fs from 'node:fs';\nimport path from 'node:path';\nfunction nameTakenByOtherPath(name: string, myPath: string): string | null {\n  const registry = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.gitnexus', 'registry.json'), 'utf8'));\n  const hit = (registry.repos ?? []).find(\n    (e: { name: string; path: string }) =>\n      e.name.toLowerCase() === name.toLowerCase() &&\n      path.resolve(e.path) !== path.resolve(myPath),\n  );\n  return hit?.path ?? null;\n}\nif (nameTakenByOtherPath('app', process.cwd())) registryName = 'app-2';","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check the registry for name collisions before registering a second same-named clone","Give CI and fork checkouts distinct --name aliases up front","Use --allow-duplicate-name only when you accept that -r <name> becomes ambiguous"],"tags":["registry","cli","name-collision","configuration"],"backgroundTag":"duplicate-name-conflict","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}