abhigyanpatwari/GitNexus · error
Failed to list repos
Error message
Failed to list repos
What it means
HTTP 500 from GET /api/repos when listRegisteredRepos() throws while reading the repository registry — the catch forwards err.message if present, else this generic text. The registry is the on-disk record of indexed repositories; this 500 means it could not be read at all (corrupt file, missing storage directory, permission problem), not that the list is empty (an empty list returns 200 with []).
Source
Thrown at gitnexus/src/server/api.ts:945
res.json({ version: pkg.version, launchContext, nodeVersion: process.version });
});
// List all registered repos
app.get('/api/repos', async (_req, res) => {
try {
const repos = await listRegisteredRepos();
res.json(
repos.map((r) => ({
name: r.name,
path: r.path,
repoPath: r.path,
indexedAt: r.indexedAt,
lastCommit: r.lastCommit,
stats: r.stats,
})),
);
} catch (err: any) {
res.status(500).json({ error: err.message || 'Failed to list repos' });
}
});
// Get repo info
// Rate-limited (CodeQL js/missing-rate-limiting): resolveRepo canonicalizes
// the attacker-supplied ?repo= param (realpathSync probe for absolute /
// Windows-shaped claims). Default 60 rpm/IP — web callers hit this route
// only on connect/switch, never in a polling loop.
app.get('/api/repo', createRouteLimiter(), async (req, res) => {
try {
const entry = await resolveRepo(requestedRepo(req), false, req);
if (!entry) {
res.status(404).json({ error: 'Repository not found. Run: gitnexus analyze' });
return;
}
// Timed out waiting for an active analysis job
if (entry.__timedOut) {
res.status(503).json({View on GitHub (pinned to aac7515d2a)
Solutions
- Check the error field in the response body and the server log — the forwarded err.message names the failing path or parse error
- Re-run `gitnexus analyze` in your repo to rewrite the registry with a known-good entry
- Fix permissions/ownership on the config/storage directory for the user running serve
- If the registry file is corrupt, remove it and re-register the repos you need (they will re-analyze)
Defensive patterns
Strategy: retry
Try / catch
async function listReposSafe(base: string, tries = 2) {
for (let i = 0; i < tries; i++) {
const res = await fetch(`${base}/api/repos`);
if (res.ok) return res.json();
if (res.status !== 500) throw new Error(`repos listing failed: ${res.status}`);
await new Promise((r) => setTimeout(r, 2000)); // transient registry read issue? retry once
}
throw new Error('registry unreadable — re-run gitnexus analyze to rebuild it');
} Prevention
- Avoid killing serve/analyze mid-write to the registry
- Keep the config/storage directory writable by the serve user
- Back up the registry when running multi-process setups
- A known-good fix is re-running gitnexus analyze to rewrite the registry
When it happens
Trigger: Corrupt or truncated registry JSON (process killed mid-write); the storage/config directory deleted or made unreadable; filesystem permission changes (running serve under a different user); concurrent registry mutation racing the read on some platforms.
Common situations: Killing gitnexus serve or analyze mid-write leaving a half-written registry; moving or renaming the home/config directory where storage lives; running the server under systemd/docker with a volume mounted read-only; multi-process setups where one process rewrote the registry in a format the other cannot parse.
Related errors
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/3336e2610838678d.
Report an issue: GitHub.