{"record":{"id":"4821acccf72b4671","repo":"abhigyanpatwari/GitNexus","slug":"refusing-to-register-resolved-metadata-belongs-to-meta","errorCode":null,"errorMessage":"Refusing to register ${resolved}: metadata belongs to ${meta.repoPath}, not this repository.","messagePattern":"Refusing to register (.+?): metadata belongs to (.+?), not this repository\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/storage/repo-manager.ts","lineNumber":984,"sourceCode":"  // which is where the cross-platform divergence actually matters.\n  const resolved = path.resolve(repoPath);\n  const storagePath =\n    opts?.storagePath === undefined\n      ? getStoragePaths(resolved).storagePath\n      : validateConfiguredStoragePath(opts.storagePath);\n\n  // Canonical form used strictly for comparison — `realpathSync.native`\n  // expands macOS /var → /private/var and Windows 8.3 → long-name,\n  // falling back to `path.resolve` when the path doesn't exist.\n  const canonicalInput = canonicalizePath(repoPath);\n\n  // Production write paths pass the storage slot they already validated. Do\n  // not let a changed environment/registry redirect their registry entry, and\n  // require the metadata receipt to describe that same repository and slot.\n  // The omitted-option path deliberately retains legacy direct-call behavior.\n  if (opts?.storagePath !== undefined) {\n    if (!registryPathEquals(canonicalizePath(meta.repoPath), canonicalInput)) {\n      throw new Error(\n        `Refusing to register ${resolved}: metadata belongs to ${meta.repoPath}, not this repository.`,\n      );\n    }\n    if (\n      meta.storagePath === undefined &&\n      !registryPathEquals(\n        canonicalizePath(storagePath),\n        canonicalizePath(defaultStoragePath(resolved)),\n      )\n    ) {\n      throw new Error(\n        `Refusing to register ${resolved}: external storage metadata must bind storagePath to the selected directory.`,\n      );\n    }\n    if (\n      meta.storagePath !== undefined &&\n      !registryPathEquals(canonicalizePath(meta.storagePath), canonicalizePath(storagePath))\n    ) {","sourceCodeStart":966,"sourceCodeEnd":1002,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/storage/repo-manager.ts#L966-L1002","documentation":"registerRepo refuses to write a registry entry when the caller passed an explicit storagePath option but the analysis metadata receipt (meta.repoPath) describes a different repository than the one being registered. This guard prevents a changed environment or redirected registry from registering storage metadata under the wrong repo. The omitted-option path intentionally keeps legacy direct-call behavior.","triggerScenarios":"Calling registerRepo with opts.storagePath set while the metadata file at that storage slot was produced for another repository path (meta.repoPath differs from the repo being registered, per canonicalized path comparison).","commonSituations":"A project directory was moved/renamed and an old .gitnexus metadata is being pointed at the new path; a copy of a repo (clone/fork) reuses the original's storage directory; GITNEXUS_STORAGE_PATH/ROOT env vars were changed between analyze and register.","solutions":["Re-run `gitnexus analyze` (or the register flow) in the target repository so fresh metadata is generated for it.","Point opts.storagePath at the storage directory that actually belongs to this repository.","Remove stale metadata from the borrowed storage directory before registering.","Omit the storagePath option if you intend legacy direct-call behavior and the metadata already matches."],"exampleFix":"// before\nawait registerRepo(\"/repos/fork\", { storagePath: \"/repos/original/.gitnexus\" });\n// after\nawait registerRepo(\"/repos/fork\", { storagePath: \"/repos/fork/.gitnexus\" });","handlingStrategy":"validation","validationCode":"import { readFile } from \"fs/promises\";\nconst meta = JSON.parse(await readFile(path.join(storagePath, \"index-meta.json\"), \"utf8\"));\nif (path.resolve(meta.repoPath) !== path.resolve(repoPath)) {\n  throw new Error(`metadata belongs to ${meta.repoPath}, not ${repoPath}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await registerRepo(repoPath, { storagePath });\n} catch (err) {\n  if (/metadata belongs to/.test(String(err))) {\n    // re-run analyze in repoPath with this storagePath, then retry\n  } else throw err;\n}","preventionTips":["Always analyze a repo with the same storagePath you later register it under.","Do not share storage directories between copies/clones of a repo.","Re-analyze after moving or renaming a project directory.","Keep GITNEXUS_STORAGE_PATH stable across commands."],"tags":["registry","storage-path","mismatch","registration"],"backgroundTag":"conflicting-config-options","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-09-15T23:29:44.066Z","contentChangedAt":"2026-09-15T23:29:44.066Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}