abhigyanpatwari/GitNexus · error · Error

Refusing to adopt branch metadata: the registry storage…

Error message

Refusing to adopt branch metadata: the registry storage path does not match the selected storage directory.

What it means

When adopting branch metadata, the code validates that the registry entry's storagePath matches the storage directory selected for the branch adoption (either resolvedStoragePath or the repo's resolved storage path). A mismatch means the registry row points at a different storage slot, and adopting branch metadata there would attach the branch index to the wrong storage.

Solutions

  1. Invoke adoption with the same storagePath recorded in the registry entry.
  2. Remove the stale registry entry (or re-register the repo) so adoption can recreate it against the selected storage directory.
  3. Re-run analyze under the same storage configuration used at registration.
  4. Unset/re-set GITNEXUS_STORAGE_PATH to match the original registration environment.

Example fix

// before
await adoptBranch(repo, branch, { storagePath: "/external/new-slot" });
// after
await adoptBranch(repo, branch, { storagePath: registryEntry.storagePath });
Defensive patterns

Strategy: validation

Validate before calling

const entries = JSON.parse(await readFile(registryPath, "utf8"));
const entry = entries.find((e) => path.resolve(e.path) === path.resolve(repoPath));
if (entry && path.resolve(entry.storagePath) !== path.resolve(selectedStoragePath)) {
  throw new Error(`registry storagePath ${entry.storagePath} != selected ${selectedStoragePath}`);
}

Try / catch

try {
  await adoptBranchMetadata(repo, branch, { storagePath });
} catch (err) {
  if (/registry storage path does not match/.test(String(err))) {
    // align storagePath with the registry entry or re-register, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: registerRepo/branch-adoption path finds an existing registry entry (initialEntries[initialIdx]) whose storagePath differs from validateConfiguredStoragePath(resolvedStoragePath) or getStoragePaths(resolved).storagePath.

Common situations: Branch metadata adoption after GITNEXUS_STORAGE_PATH changed; the repo's registry entry was created under a default .gitnexus path but adoption now targets an external slot (or vice versa); registry rows copied between machines with different absolute paths.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15). Data as JSON: /api/errors/9a04aa774d74902a. Report an issue: GitHub.

Appendix: source

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

  resolvedStoragePath?: string,
): Promise<void> => {
  const canonicalInput = canonicalizePath(repoPath);
  const isRegistered = (list: RegistryEntry[]): number =>
    list.findIndex((e) => registryPathEquals(canonicalizePath(e.path), canonicalInput));
  // Cheap membership gate only (#2364 review F2): never touch the disk for an
  // unregistered repo. The mutate below re-reads its own fresh snapshot.
  const initialEntries = await readRegistry();
  const initialIdx = isRegistered(initialEntries);
  if (initialIdx < 0) return; // no-op, disk included (no self-heal)

  const resolved = path.resolve(repoPath);
  const storagePath =
    resolvedStoragePath === undefined
      ? getStoragePaths(resolved).storagePath
      : validateConfiguredStoragePath(resolvedStoragePath);
  const registeredStoragePath = initialEntries[initialIdx].storagePath;
  if (!registryPathEquals(canonicalizePath(registeredStoragePath), canonicalizePath(storagePath))) {
    throw new Error(
      `Refusing to adopt branch metadata: the registry storage path does not match the selected storage directory.`,
    );
  }
  if (resolvedStoragePath !== undefined) {
    const inspection = await inspectStoragePath(storagePath, resolved);
    if (inspection.state !== 'owned') {
      throw new Error(
        `Refusing to adopt branch metadata: storage is not owned by this repository (${inspection.state}).`,
      );
    }
  }
  // Remove a shadowed sub-index directory, mirroring `clean --branch`'s
  // containment guard: the target MUST live under .gitnexus/branches/.
  const branchesRoot = path.join(storagePath, BRANCHES_DIR);
  const branchDir = path.join(branchesRoot, branchSlug(branch));
  const branchRelativePath = path.relative(branchesRoot, branchDir);
  const branchDirIsContained =
    branchRelativePath !== '' &&

View on GitHub (pinned to ac9a4e9abd)