{"record":{"id":"5063248f66c24d6f","repo":"abhigyanpatwari/GitNexus","slug":"repository-not-found-run-gitnexus-analyze","errorCode":null,"errorMessage":"Repository not found. Run: gitnexus analyze","messagePattern":"Repository not found\\. Run: gitnexus analyze","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":958,"sourceCode":"          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({\n          error: `Repository analysis for \"${entry.repoName}\" is taking longer than expected. Please try again in a moment.`,\n        });\n        return;\n      }\n      const meta = await loadMeta(entry.storagePath);\n      res.json({\n        name: entry.name,\n        repoPath: entry.path,\n        indexedAt: meta?.indexedAt ?? entry.indexedAt,\n        stats: meta?.stats ?? entry.stats ?? {},\n      });\n    } catch (err: any) {\n      res.status(500).json({ error: err.message || 'Failed to get repo info' });","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/server/api.ts#L940-L976","documentation":"HTTP 404 from GET /api/repo when resolveRepo cannot find the requested repository: either the ?repo= name does not match a registered repo, or no ?repo= was given and the server's default resolution found nothing. The route is rate-limited (60 rpm/IP by default) because resolveRepo canonicalizes the attacker-supplied repo parameter. The remediation message is baked in: the repository must be indexed first with `gitnexus analyze` before the API can serve metadata for it.","triggerScenarios":"GET /api/repo?repo=wrong-name where the registered name differs (case, org prefix, .git suffix); starting gitnexus serve in a fresh clone that has never been analyzed; querying after the index storage was wiped; web UI connecting before the first analysis finished registering.","commonSituations":"New contributor clones the repo, runs serve, opens the web UI, and gets this before their first analyze; name mismatches between what the UI sends and the registry entry; switching serve between multiple repos with stale UI state; CI ephemeral checkouts with cold indexes.","solutions":["Run `gitnexus analyze` in the repository root, wait for it to register, then retry the request","Discover the exact registered name via GET /api/repos and send ?repo=<that exact name>","If you meant the default repo, start serve from that repo's root directory","For upload-based flows, poll the analysis job until it completes — only then does /api/repo resolve"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the repo is registered before connecting the UI.\nconst repos = await (await fetch(`${base}/api/repos`)).json();\nif (!repos.some((r: { name: string }) => r.name === targetRepo)) {\n  throw new Error(`run 'gitnexus analyze' in ${targetRepo} first`);\n}","typeGuard":null,"tryCatchPattern":"const res = await fetch(`${base}/api/repo?repo=${encodeURIComponent(name)}`);\nif (res.status === 404 && /Run: gitnexus analyze/.test((await res.json()).error)) {\n  await runAnalyze(name); // or guide the user to\n  return fetch(`${base}/api/repo?repo=${encodeURIComponent(name)}`);\n}","preventionTips":["Make 'analyze before serve' part of the setup script","Validate the repo name against GET /api/repos at connect time","Use the exact registered name (watch case and suffixes)"],"tags":["http-404","repository","indexing","api"],"backgroundTag":"repository-not-found","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}