{"record":{"id":"72c952031f99756a","repo":"abhigyanpatwari/GitNexus","slug":"body","errorCode":null,"errorMessage":"body","messagePattern":"body","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"gitnexus/src/server/api.ts","lineNumber":1378,"sourceCode":"        readOnlyFtsOptions(skipFts),\n      );\n      res.json(graph);\n    } catch (err: any) {\n      if (sendStorageRequirementHttp(err, res)) return;\n      if (err instanceof ClientDisconnectedError) {\n        return;\n      }\n      const body = httpErrorBody(err, 'Failed to build graph');\n      if (res.headersSent) {\n        try {\n          res.write(JSON.stringify({ type: 'error', ...body }) + '\\n');\n        } catch {\n          // Best-effort only after streaming has started.\n        }\n        res.end();\n        return;\n      }\n      res.status(500).json(body);\n    }\n  });\n\n  // Execute Cypher query\n  app.post('/api/query', async (req, res) => {\n    await handleQueryRequest(req, res, resolveRepo);\n  });\n\n  // Search (supports mode: 'hybrid' | 'semantic' | 'bm25', and optional enrichment)\n  app.post('/api/search', async (req, res) => {\n    try {\n      const query = (req.body.query ?? '').trim();\n      if (!query) {\n        res.status(400).json({ error: 'Missing \"query\" in request body' });\n        return;\n      }\n\n      const entry = await resolveRepo(requestedRepo(req));","sourceCodeStart":1360,"sourceCodeEnd":1396,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/server/api.ts#L1360-L1396","documentation":"A generic 500 response: when a streaming response handler hits an error after headers may already have been sent, it tries a best-effort abort and otherwise returns `res.status(500).json(body)`. The `body` here is the pre-built error object describing why the request failed server-side.","triggerScenarios":"Any endpoint using this streaming error wrapper whose handler throws before streaming starts — e.g. an internal error while resolving the repo or preparing the streamed result — results in the 500 JSON body.","commonSituations":"Developers see this when the underlying query/search handler fails unexpectedly: corrupted index, failed repo resolution, or a bug in a handler that doesn't map its error to a specific status code.","solutions":["Inspect the 500 body's error/message fields for the underlying cause","Check GitNexus server logs around the request for the full stack trace","Re-run `gitnexus analyze --index-only` if the index appears corrupted or stale","Retry the request; if reproducible, report the stack trace as a bug"],"exampleFix":"// before: ignoring the 500 body\nconst res = await fetch(url); // 500\nconsole.log(res.status);\n\n// after: surface the server-provided cause\nconst res = await fetch(url);\nif (!res.ok) console.error(await res.json()); // { error: '...' }","handlingStrategy":"try-catch","validationCode":"if (!res.ok && res.status === 500) {\n  const body = await res.json();\n  console.error('server error:', body.error ?? body);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(streamUrl);\n  if (res.status === 500) {\n    const body = await res.json(); // error object carries the real cause\n    throw new Error(body.error ?? 'stream failed before start');\n  }\n  // ... consume stream\n} catch (e) {\n  console.error(e); retryOrReport();\n}","preventionTips":["Always parse the 500 body — it contains the server-side cause","Keep the index fresh (`analyze --index-only`) to avoid corruption-driven failures","Capture server logs when reproducing; report persistent 500s with the body"],"tags":["http-500","internal","streaming","unexpected"],"backgroundTag":"internal-invariant-violation","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"}