{"record":{"id":"56872281a0fd2ef8","repo":"abhigyanpatwari/GitNexus","slug":"gitnexus-bm25-fts-search-failed-fts-indexes-may","errorCode":null,"errorMessage":"GitNexus: BM25/FTS search failed (FTS indexes may not exist) — falling back to semantic-only","messagePattern":"GitNexus: BM25/FTS search failed \\(FTS indexes may not exist\\) — falling back to semantic-only","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/mcp/local/local-backend.ts","lineNumber":3095,"sourceCode":"      ({ searchFTSFromLbug } = await import('../../core/search/bm25-index.js'));\n    } catch (err: any) {\n      // Module import can fail in sandboxed MCP contexts (#1489)\n      logger.warn(\n        { err: err?.message },\n        'GitNexus: bm25-index.js import failed — falling back to semantic-only',\n      );\n      return { results: [], ftsUsed: false };\n    }\n    let ftsResponse;\n    try {\n      ftsResponse = await searchFTSFromLbug(query, limit, repo.lbugPath);\n    } catch (err: any) {\n      // Swallowed, gracefully-degraded failure: the search falls back to\n      // semantic-only (a valid result), and the most common cause is simply an\n      // un-indexed FTS extension — a normal configuration, not an operation\n      // error. Logged at warn (matching the sibling import-failure fallback\n      // above), never error, so it does not raise a false alarm.\n      logger.warn(\n        { err: err.message },\n        'GitNexus: BM25/FTS search failed (FTS indexes may not exist) — falling back to semantic-only',\n      );\n      return { results: [], ftsUsed: false };\n    }\n\n    // Guard against unexpected response shape (#1489) — ftsResponse.results\n    // could be undefined when the FTS extension is unavailable in the MCP process.\n    const bm25Results = ftsResponse?.results ?? [];\n    const ftsUsed = ftsResponse?.ftsAvailable ?? false;\n    const nonBenignErrors = ftsResponse?.nonBenignErrors;\n\n    const results: any[] = [];\n\n    for (const bm25Result of bm25Results) {\n      const fullPath = bm25Result.filePath;\n      try {\n        // Prefer direct nodeId lookup (exact FTS-matched nodes) over filePath fallback.","sourceCodeStart":3077,"sourceCodeEnd":3113,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/mcp/local/local-backend.ts#L3077-L3113","documentation":"searchFTSFromLbug(query, limit, repo.lbugPath) threw after the module imported fine. The most common cause is simply an un-indexed FTS extension — a normal configuration — so it is swallowed as a graceful degrade to semantic-only with ftsUsed:false, logged at warn (never error) to match the sibling import-failure fallback and avoid false alarms.","triggerScenarios":"BM25 search runs against a repo whose LadybugDB has no FTS indexes (index built without FTS, or the FTS extension unavailable in the MCP process); the query call then throws instead of returning an empty ftsAvailable:false response.","commonSituations":"Repos analyzed by versions/configurations that skip FTS creation; MCP processes loading a LadybugDB build without the FTS extension; fresh DBs queried before a completed analyze.","solutions":["Re-run `gitnexus analyze` so FTS indexes are (re)built for the DB.","Verify the LadybugDB build in use includes the FTS extension (reinstall the package to get the matching prebuild).","Treat results as semantic-only meanwhile — the response's ftsUsed flag tells you BM25 contributed nothing.","Check the logged err message: anything beyond a missing-index/binder error indicates a real fault worth fixing."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Before searching: confirm FTS exists for this repo's DB\nconst probe = await searchFTSFromLbug('__probe__', 1, repo.lbugPath);\nif (!probe.ftsAvailable) flagSemanticOnly(repo); // expected warn avoided, behavior unchanged","typeGuard":null,"tryCatchPattern":"try {\n  ftsResponse = await searchFTSFromLbug(query, limit, repo.lbugPath);\n} catch (err) {\n  logger.warn({ err: err.message }, 'falling back to semantic-only');\n  return { results: [], ftsUsed: false };\n}","preventionTips":["Run a completed analyze before serving queries against a fresh DB.","Treat ftsUsed:false in results as the structured signal of this fallback.","Keep the CLI that indexed and the MCP process on the same LadybugDB build."],"tags":["mcp","fts","bm25","semantic-fallback","ladybugdb"],"backgroundTag":"fts-index-missing","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-08-31T04:17:50.494Z"}