{"record":{"id":"3336e2610838678d","repo":"abhigyanpatwari/GitNexus","slug":"failed-to-list-repos","errorCode":null,"errorMessage":"Failed to list repos","messagePattern":"Failed to list repos","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":945,"sourceCode":"    res.json({ version: pkg.version, launchContext, nodeVersion: process.version });\n  });\n\n  // List all registered repos\n  app.get('/api/repos', async (_req, res) => {\n    try {\n      const repos = await listRegisteredRepos();\n      res.json(\n        repos.map((r) => ({\n          name: r.name,\n          path: r.path,\n          repoPath: r.path,\n          indexedAt: r.indexedAt,\n          lastCommit: r.lastCommit,\n          stats: r.stats,\n        })),\n      );\n    } catch (err: any) {\n      res.status(500).json({ error: err.message || 'Failed to list repos' });\n    }\n  });\n\n  // Get repo info\n  // Rate-limited (CodeQL js/missing-rate-limiting): resolveRepo canonicalizes\n  // the attacker-supplied ?repo= param (realpathSync probe for absolute /\n  // Windows-shaped claims). Default 60 rpm/IP — web callers hit this route\n  // only on connect/switch, never in a polling loop.\n  app.get('/api/repo', createRouteLimiter(), async (req, res) => {\n    try {\n      const entry = await resolveRepo(requestedRepo(req), false, req);\n      if (!entry) {\n        res.status(404).json({ error: 'Repository not found. Run: gitnexus analyze' });\n        return;\n      }\n      // Timed out waiting for an active analysis job\n      if (entry.__timedOut) {\n        res.status(503).json({","sourceCodeStart":927,"sourceCodeEnd":963,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/server/api.ts#L927-L963","documentation":"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 []).","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function listReposSafe(base: string, tries = 2) {\n  for (let i = 0; i < tries; i++) {\n    const res = await fetch(`${base}/api/repos`);\n    if (res.ok) return res.json();\n    if (res.status !== 500) throw new Error(`repos listing failed: ${res.status}`);\n    await new Promise((r) => setTimeout(r, 2000)); // transient registry read issue? retry once\n  }\n  throw new Error('registry unreadable — re-run gitnexus analyze to rebuild it');\n}","preventionTips":["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"],"tags":["http-500","registry","api","filesystem"],"backgroundTag":"registry-read-failed","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}