abhigyanpatwari/GitNexus · warning

GitNexus: bm25-index.js import failed — falling back to sema

Error message

GitNexus: bm25-index.js import failed — falling back to semantic-only

What it means

The dynamic import of ../../core/search/bm25-index.js inside bm25Search failed (module resolution, sandboxed MCP contexts per #1489, broken install). The helper returns { results: [], ftsUsed: false } and the overall search degrades to semantic-only — a valid result, not an operation error.

Source

Thrown at gitnexus/src/mcp/local/local-backend.ts:3080

      ...(warnings.length > 0 && { warning: warnings.join(' ') }),
      ...((enrichmentDegraded || ftsPartial) && { partial: true }),
    };
  }

  /**
   * BM25 keyword search helper - uses LadybugDB FTS for always-fresh results
   */
  private async bm25Search(
    repo: RepoHandle,
    query: string,
    limit: number,
  ): Promise<{ results: any[]; ftsUsed: boolean; nonBenignErrors?: string[] }> {
    let searchFTSFromLbug;
    try {
      ({ searchFTSFromLbug } = await import('../../core/search/bm25-index.js'));
    } catch (err: any) {
      // Module import can fail in sandboxed MCP contexts (#1489)
      logger.warn(
        { err: err?.message },
        'GitNexus: bm25-index.js import failed — falling back to semantic-only',
      );
      return { results: [], ftsUsed: false };
    }
    let ftsResponse;
    try {
      ftsResponse = await searchFTSFromLbug(query, limit, repo.lbugPath);
    } catch (err: any) {
      // Swallowed, gracefully-degraded failure: the search falls back to
      // semantic-only (a valid result), and the most common cause is simply an
      // un-indexed FTS extension — a normal configuration, not an operation
      // error. Logged at warn (matching the sibling import-failure fallback
      // above), never error, so it does not raise a false alarm.
      logger.warn(
        { err: err.message },
        'GitNexus: BM25/FTS search failed (FTS indexes may not exist) — falling back to semantic-only',
      );

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Loosen the MCP sandbox to allow reading files under the installed gitnexus package directory.
  2. Reinstall cleanly: `rm -rf node_modules && npm install gitnexus@latest`.
  3. Verify the file exists: check node_modules/gitnexus/dist/core/search/bm25-index.js (or the source path in dev).
  4. Accept semantic-only results temporarily — search still works without BM25.
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-flight the module once at server startup instead of per query
let bm25: typeof import('../../core/search/bm25-index.js') | undefined;
try { bm25 = await import('../../core/search/bm25-index.js'); }
catch { bm25 = undefined; } // search config now knows FTS is unavailable

Try / catch

let searchFTSFromLbug;
try {
  ({ searchFTSFromLbug } = await import('../../core/search/bm25-index.js'));
} catch {
  return { results: [], ftsUsed: false }; // semantic-only is a valid result
}

Prevention

When it happens

Trigger: A `query`/search MCP call enters bm25Search; `await import('../../core/search/bm25-index.js')` throws in restricted MCP sandboxes (file-read policies, ESM loader restrictions) or when the package install is incomplete. Only err?.message is captured in the log.

Common situations: MCP servers run under sandbox policies (seatbelt/bubblewrap profiles) that block reading module files inside the package; partially-installed node_modules after an interrupted npm install; bundlers that break the relative ESM path.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20). Data as JSON: /api/errors/dab95a2459cadab3. Report an issue: GitHub.