abhigyanpatwari/GitNexus · error · AnalysisNotFinalizedError
Analysis not finalized: missing registry-entry for
Error message
Analysis not finalized: missing registry-entry for ${resolved} at ${storagePath} (registry: ${getGlobalRegistryPath()}) What it means
AnalysisNotFinalizedError with kind 'registry-entry' means the metadata file exists at storagePath but readRegistryStrict found no registry entry pairing this repository path with this storagePath. Analysis is only considered finalized when both the on-disk metadata and a matching strict-read registry row exist.
Solutions
- Re-run `gitnexus analyze` with the same storage configuration so registration completes and the registry row is written.
- Fix the registry file to include an entry pairing the repo path with this storagePath (or remove the orphan metadata and re-analyze).
- Align GITNEXUS_STORAGE_PATH / storagePath option between the analyze and consuming commands.
- Check the registry path in the message — you may be consulting a different registry than the one populated during analyze.
Example fix
// before
await ensureFinalized(repo, { storagePath: "/external/slot" }); // no registry row
// after
await registerRepo(repo, { storagePath: "/external/slot" });
await ensureFinalized(repo, { storagePath: "/external/slot" }); Defensive patterns
Strategy: validation
Validate before calling
const entries = JSON.parse(await readFile(registryPath, "utf8"));
const ok = entries.some((e) =>
path.resolve(e.path) === path.resolve(repoPath) &&
path.resolve(e.storagePath) === path.resolve(storagePath));
if (!ok) await registerRepo(repoPath, { storagePath }); Try / catch
try {
await readIndex(repoPath, { storagePath });
} catch (err) {
if (err instanceof AnalysisNotFinalizedError && err.kind === "registry-entry") {
await registerRepo(repoPath, { storagePath }); // write the missing row
await readIndex(repoPath, { storagePath });
} else throw err;
} Prevention
- Complete the full analyze+register flow; don't abort midway.
- Back up the registry file and validate it after restores.
- Use identical storage configuration (env vars/options) for all commands on a repo.
- If a metadata file exists but no row matches, re-analyze to resynchronize.
When it happens
Trigger: A finalize/read path finds meta at storagePath, but no entry in the global registry has entry.path == repo and entry.storagePath == storagePath (canonicalized comparison) — the metadata is present while the registry row is missing or points elsewhere.
Common situations: The registry file was manually edited, truncated, or restored from an older backup losing the row; the repo was analyzed with default storage but is now read with an explicit storagePath; registration failed midway after metadata write; environment (GITNEXUS_STORAGE_PATH) differs between analyze and read.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Refusing to register
- Refusing to register
- Refusing to adopt branch metadata: the registry storage…
- Refusing to register
- Analysis did not finalize for
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/88c69444ae8e3e87.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/storage/repo-manager.ts:1480
? getStoragePaths(resolved).storagePath
: validateConfiguredStoragePath(resolvedStoragePath);
const metaPath = path.join(storagePath, INDEX_METADATA_FILE);
try {
await fs.access(metaPath);
} catch {
throw new AnalysisNotFinalizedError(resolved, storagePath, 'meta', getGlobalRegistryPath());
}
const canonicalRepoPath = canonicalizePath(resolved);
const canonicalStoragePath = canonicalizePath(storagePath);
const registeredAtStoragePath = (await readRegistryStrict()).some(
(entry) =>
registryPathEquals(canonicalizePath(entry.path), canonicalRepoPath) &&
registryPathEquals(canonicalizePath(entry.storagePath), canonicalStoragePath),
);
if (!registeredAtStoragePath) {
throw new AnalysisNotFinalizedError(
resolved,
storagePath,
'registry-entry',
getGlobalRegistryPath(),
);
}
};
/**
* Thrown by {@link assertSafeStoragePath} when {@link requireDeletableStoragePath}
* rejects the registry entry. Repository-local `.gitnexus` may still be
* removed when it is missing, empty, unowned, or foreign; an external slot
* is removable only when metadata binds both the repository and that exact
* path. CLI destructive commands (`remove`, `clean --all`) should catch this
* and exit non-zero without deleting anything.
*/
export class UnsafeStoragePathError extends Error {
readonly kind = 'UnsafeStoragePathError' as const;View on GitHub (pinned to ac9a4e9abd)