abhigyanpatwari/GitNexus · error · Error
Refusing to register
Error message
Refusing to register ${resolved}: metadata storagePath does not match the selected storage directory. What it means
registerRepo refuses registration when the metadata receipt's meta.storagePath does not match the storagePath option the caller selected. Production write paths must register the exact storage slot they validated; a mismatch means the metadata belongs to a different storage directory and the registry entry would be wrong.
Solutions
- Pass the same storagePath the metadata records (read it from the metadata file under the storage directory).
- Re-run analyze so metadata is regenerated bound to the currently selected storagePath.
- Update or delete the stale metadata file, then re-analyze and register.
- Set GITNEXUS_STORAGE_PATH identically for both analyze and register runs.
Example fix
// before
await registerRepo(repo, { storagePath: "/old/slot" }); // meta.storagePath: "/new/slot"
// after
await registerRepo(repo, { storagePath: "/new/slot" }); Defensive patterns
Strategy: validation
Validate before calling
const meta = JSON.parse(await readFile(path.join(storagePath, "index-meta.json"), "utf8"));
if (meta.storagePath !== undefined && path.resolve(meta.storagePath) !== path.resolve(storagePath)) {
throw new Error(`meta.storagePath ${meta.storagePath} != selected ${storagePath}`);
} Try / catch
try {
await registerRepo(repoPath, { storagePath });
} catch (err) {
if (/metadata storagePath does not match/.test(String(err))) {
// read meta.storagePath and pass that, or re-analyze, then retry
} else throw err;
} Prevention
- Pass the storagePath exactly as recorded in the metadata receipt.
- Re-analyze after moving or renaming external storage directories.
- Avoid symlinks/relative paths when specifying storagePath; use canonical absolute paths.
- Keep storage configuration consistent in CI between analyze and register steps.
When it happens
Trigger: Calling registerRepo with opts.storagePath set while meta.storagePath exists but canonicalizes to a different directory (moved slot, renamed directory, symlink path differences resolved differently).
Common situations: The external storage directory was moved or renamed after analysis; a different GITNEXUS_STORAGE_PATH was exported in the registering shell than in the analyzing one; registering a copied repo whose metadata still points at the source repo's slot.
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
- Refusing to adopt branch metadata: the registry storage…
- Refusing to register
- Refusing to register
- Analysis not finalized: missing registry-entry for
- Analysis did not finalize for
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/6ef8c98b489925d0.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/storage/repo-manager.ts:1003
`Refusing to register ${resolved}: metadata belongs to ${meta.repoPath}, not this repository.`,
);
}
if (
meta.storagePath === undefined &&
!registryPathEquals(
canonicalizePath(storagePath),
canonicalizePath(defaultStoragePath(resolved)),
)
) {
throw new Error(
`Refusing to register ${resolved}: external storage metadata must bind storagePath to the selected directory.`,
);
}
if (
meta.storagePath !== undefined &&
!registryPathEquals(canonicalizePath(meta.storagePath), canonicalizePath(storagePath))
) {
throw new Error(
`Refusing to register ${resolved}: metadata storagePath does not match the selected storage directory.`,
);
}
}
// Mutating writes must not treat an unreadable/truncated registry as empty
// (#3094): lenient `readRegistry()` returns `[]` on parse failure and would
// replace the machine-wide file with only this entry. ENOENT stays empty.
const entries = await readRegistryStrict();
const existingIdx = entries.findIndex((e) => {
// Canonicalise the STORED entry too so pre-canonicalisation
// registries (written by older versions, or paths passed in a
// different form) still match correctly. `canonicalizePath` falls
// back to `path.resolve` when the path no longer exists on disk,
// so stale entries that have been rm'd externally still resolve
// to a stable key instead of throwing.
const a = canonicalizePath(e.path);
const b = canonicalInput;View on GitHub (pinned to ac9a4e9abd)