{"record":{"id":"49f0ac4af33dd8ce","repo":"abhigyanpatwari/GitNexus","slug":"file-not-found","errorCode":null,"errorMessage":"File not found","messagePattern":"File not found","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":633,"sourceCode":"    if (startLine !== undefined && Number.isFinite(startLine)) {\n      const lines = raw.split('\\n');\n      const start = Math.max(0, startLine);\n      const end =\n        endLine !== undefined && Number.isFinite(endLine)\n          ? Math.min(lines.length, endLine + 1)\n          : lines.length;\n      res.json({\n        content: lines.slice(start, end).join('\\n'),\n        startLine: start,\n        endLine: end - 1,\n        totalLines: lines.length,\n      });\n    } else {\n      res.json({ content: raw, totalLines: raw.split('\\n').length });\n    }\n  } catch (err: any) {\n    if (err.code === 'ENOENT') {\n      res.status(404).json({ error: 'File not found' });\n    } else {\n      // statusFromError returns err.status for BadRequestError / ForbiddenError\n      // (assertString → 400 on array-form ?path=a&path=b; ForbiddenError → 403\n      // on traversal). Falls back to 500 for unrecognized failures.\n      res.status(statusFromError(err)).json({ error: err.message || 'Failed to read file' });\n    }\n  }\n};\n\nexport const handleQueryRequest = async (\n  req: express.Request,\n  res: express.Response,\n  resolveRepo: (repoName?: string) => Promise<{ storagePath: string } | undefined>,\n): Promise<void> => {\n  try {\n    const cypher = req.body.cypher as string;\n    if (!cypher) {\n      res.status(400).json({ error: 'Missing \"cypher\" in request body' });","sourceCodeStart":615,"sourceCodeEnd":651,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/server/api.ts#L615-L651","documentation":"HTTP 404 from the repo file-read API when fs.readFile throws ENOENT after the request passed validation and traversal containment — the path was well-formed and inside the repo, but no such file exists on disk. The handler distinguishes err.code === 'ENOENT' from other failures, which fall through to statusFromError (400/403/500). Note the API reads the real filesystem, not the index, so a file present in stale index results but deleted from the working tree will still 404.","triggerScenarios":"Requesting a file deleted or renamed since it was indexed; a case mismatch on case-sensitive filesystems (README.md vs readme.md); pointing at the wrong repo (?repo=) where the relative path does not exist; requesting a path that only exists on another branch.","commonSituations":"Web UI holding stale grep/query results after a branch switch or rebase; files generated at index time but later cleaned (build artifacts); developers testing with paths from their laptop on a CI checkout that differs; typo in the filename.","solutions":["Verify the file exists in the working tree of the served repository (git status / ls) at the exact case","Re-run gitnexus analyze or re-fetch search results so the UI's paths match the current tree","Check you are querying the right repository (?repo= matches the repo containing the file)","Handle 404 gracefully in the UI by invalidating cached result entries that reference the missing path"],"exampleFix":"// before\nconst res = await fetch(`${base}/api/file?path=${hit.path}`);\nconst body = await res.json(); // { error: 'File not found' } breaks the viewer\n\n// after\nconst res = await fetch(`${base}/api/file?path=${encodeURIComponent(hit.path)}`);\nif (res.status === 404) { removeFromResults(hit); notifyUser('File no longer exists — results refreshed'); return; }","handlingStrategy":"validation","validationCode":"// Only request files that the current results/tree actually reference.\nif (!tree.has(filePath)) {\n  await refreshIndex(); // re-fetch grep/query results or re-run analyze\n  if (!tree.has(filePath)) throw new Error(`file not in current tree: ${filePath}`);\n}","typeGuard":null,"tryCatchPattern":"const res = await fetch(fileUrl);\nif (res.status === 404 && (await res.json()).error === 'File not found') {\n  dropStaleResult(filePath); // invalidate cached references instead of crashing the viewer\n  return null;\n}","preventionTips":["Refresh search results after branch switches or rebases","Match filename case exactly, especially on case-sensitive filesystems","Confirm ?repo= points at the repository that contains the file"],"tags":["http-404","file-not-found","api","filesystem"],"backgroundTag":"file-not-found","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}