abhigyanpatwari/GitNexus · error · Error
entry does not identify a repo — name and storagePath must…
Error message
${getGlobalRegistryPath()} entry ${bad} does not identify a repo — name and storagePath must be non-empty strings and path must be a string (registry is corrupt) What it means
parseRegistryContents in strict mode throws when any entry in the global registry file fails isResolvableEntry: name and storagePath must be non-empty strings and path must be a string. Strict mode deliberately rejects the whole registry rather than filtering bad rows, because silently dropping entries would report valid repos as unregistered. The message includes the zero-based index of the offending entry.
Solutions
- Open the registry file at the path in the message, find the entry at the reported index, and fix or delete that entry.
- Back up the registry file, then remove corrupt rows and re-register affected repos with `gitnexus analyze`/register.
- Restore the registry file from backup or source control if available.
- Avoid hand-editing the registry; let gitnexus manage it.
Example fix
// before (registry.json, entry 2)
{ "path": "~/proj", "name": "" }
// after
{ "path": "~/proj", "name": "proj", "storagePath": "/home/me/proj/.gitnexus" } Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from "fs";
const registry = JSON.parse(readFileSync(registryPath, "utf8"));
const bad = registry.findIndex((e) =>
!e || typeof e.path !== "string" || typeof e.name !== "string" || !e.name ||
typeof e.storagePath !== "string" || !e.storagePath);
if (bad !== -1) throw new Error(`corrupt registry entry at index ${bad}`); Type guard
function isResolvableEntry(e: unknown): e is { path: string; name: string; storagePath: string } {
const r = e as Record<string, unknown>;
return typeof r?.path === "string" && typeof r?.name === "string" && r.name !== "" &&
typeof r?.storagePath === "string" && r.storagePath !== "";
} Try / catch
try {
const repos = await readRegistryFile();
} catch (err) {
// parseRegistryContents throws plain Error on corrupt rows
if (/registry is corrupt/.test(String(err))) {
// restore from backup or excise the reported entry index, then retry
} else throw err;
} Prevention
- Never hand-edit the registry file; use gitnexus commands.
- Keep a backup of the registry before manual maintenance.
- Ensure clean shutdown (avoid SIGKILL) so writes are not truncated.
- Watch for version mismatches when upgrading gitnexus.
When it happens
Trigger: readRegistryFile or readRegistryStrictIfPresent reads the global registry JSON and one entry lacks a non-empty `name`, a non-empty `storagePath`, or a string `path` while strict mode is on.
Common situations: Manual hand-editing of the registry file introducing malformed rows; a crash or disk-full during a registry write leaving truncated JSON; an older gitnexus version writing a registry shape the current reader no longer accepts; external tooling rewriting the file.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Metadata file exists but is unreadable/corrupt; leaving…
- parsedfile-store: dropped malformed/over-bound sites at…
- parsedfile-store: rejected shard entries at load (untrusted…
- Refusing to adopt branch metadata: storage is not owned by…
- Refusing to delete storage
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/0040a2d044b67458.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/storage/repo-manager.ts:741
const entries = data.map((entry) =>
entry &&
typeof entry === 'object' &&
!Array.isArray(entry) &&
typeof (entry as Record<string, unknown>).path === 'string' &&
(entry as Record<string, unknown>).storagePath === undefined
? {
...(entry as Record<string, unknown>),
storagePath: defaultStoragePath((entry as Record<string, unknown>).path as string),
}
: entry,
) as RegistryEntry[];
if (strict) {
// Reject the WHOLE registry, never filter the bad rows out. Dropping them
// would report the repos they name as unregistered, which is precisely
// the unreadable-as-missing answer this mode refuses to give.
const bad = entries.findIndex((entry) => !isResolvableEntry(entry));
if (bad !== -1) {
throw new Error(
`${getGlobalRegistryPath()} entry ${bad} does not identify a repo — name and storagePath must be non-empty strings and path must be a string (registry is corrupt)`,
);
}
}
return sanitizeEntries(entries);
} catch (err) {
if (strict) throw err;
return [];
}
};
const readRegistryFile = async (strict: boolean): Promise<RegistryEntry[]> => {
let raw: string;
try {
raw = await fs.readFile(getGlobalRegistryPath(), 'utf-8');
} catch (err) {
if (strict && (err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;
return [];View on GitHub (pinned to ac9a4e9abd)