{"record":{"id":"7adafa330e840c99","repo":"abhigyanpatwari/GitNexus","slug":"failed-to-read-file","errorCode":null,"errorMessage":"Failed to read file","messagePattern":"Failed to read file","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":1578,"sourceCode":"    } catch (err: any) {\n      if (sendStorageRequirementHttp(err, res)) return;\n      res.status(500).json(httpErrorBody(err, 'Search failed'));\n    }\n  });\n\n  // Read file — with path traversal guard\n  // Rate-limited (CodeQL js/missing-rate-limiting): per-request fs.readFile.\n  app.get('/api/file', createRouteLimiter(), async (req, res) => {\n    try {\n      const entry = await resolveRepo(requestedRepo(req));\n      if (!entry) {\n        res.status(404).json({ error: 'Repository not found' });\n        return;\n      }\n      await handleFileRequest(req, res, entry.path, await getSourceAvailability(entry));\n    } catch (err: any) {\n      if (sendStorageRequirementHttp(err, res)) return;\n      res.status(500).json({ error: err.message || 'Failed to read file' });\n    }\n  });\n\n  // Grep — regex search across file contents in the indexed repo\n  // Uses filesystem-based search for memory efficiency (never loads all files into memory)\n  // Rate-limited (CodeQL js/missing-rate-limiting): scans every file in\n  // the indexed repo per request — heaviest I/O endpoint. Same default 60\n  // rpm/IP for now; consider tightening if real-world load shows abuse.\n  app.get('/api/grep', createRouteLimiter(), async (req, res) => {\n    try {\n      const entry = await resolveRepo(requestedRepo(req));\n      if (!entry) {\n        res.status(404).json({ error: 'Repository not found' });\n        return;\n      }\n      const sourceAvailability = await getSourceAvailability(entry);\n      if (!sourceAvailability.available) {\n        sendSourceUnavailable(res, sourceAvailability);","sourceCodeStart":1560,"sourceCodeEnd":1596,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/server/api.ts#L1560-L1596","documentation":"A 500 response from the file-read endpoint (GET /api/file). If the requested file cannot be read and the error is not a storage-requirement error (which maps to 410), the handler returns err.message or the fallback 'Failed to read file'.","triggerScenarios":"GET /api/file?path=... where handleFileRequest throws: the path resolves outside the repo (traversal guard), the file was deleted after indexing, or a filesystem error occurs during readFile.","commonSituations":"Common when the working tree changed since indexing (file renamed/removed), the requested path uses wrong relative form, or the repo checkout moved on disk.","solutions":["Verify the requested path exists in the repo working tree and is relative to the repo root","Re-run `gitnexus analyze` to refresh the index if the working tree changed since indexing","Check file permissions on the file for the server process user","If the response is 410 (not this 500), the index uses non-full content retention — re-analyze or use local file access"],"exampleFix":"// before: requesting a file that moved\nfetch('/api/file?path=src/old-name.ts') // 500 Failed to read file\n\n// after: refresh index / use the current path\ncd my-repo && gitnexus analyze\nfetch('/api/file?path=src/new-name.ts') // 200","handlingStrategy":"validation","validationCode":"import { existsSync } from 'fs';\nconst p = path.resolve(repoRoot, relPath);\nif (!p.startsWith(path.resolve(repoRoot) + path.sep) || !existsSync(p)) throw new Error('bad file path');","typeGuard":null,"tryCatchPattern":"const res = await fetch(`/api/file?path=${encodeURIComponent(p)}`);\nif (res.status === 500) {\n  const { error } = await res.json();\n  console.warn('File read failed:', error); // re-index or fix the path\n}","preventionTips":["Use repo-relative paths exactly as returned by search results","Re-run `gitnexus analyze` whenever the working tree changes (renames/deletes)","Handle 410 separately: it means content retention is off, not a read failure"],"tags":["http-500","file-read","filesystem","path"],"backgroundTag":"file-read-failed","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-09-15T23:29:44.066Z","contentChangedAt":"2026-09-15T23:29:44.066Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}