abhigyanpatwari/GitNexus · error · Error

FTS repair failed - missing indexes after rebuild: ${missing

Error message

FTS repair failed - missing indexes after rebuild: ${missing.join(', ')}.${reasons} Run `gitnexus analyze --force` to perform a full graph+FTS rebuild; if that also fails, verify FTS extension availability via `gitnexus doctor`.

What it means

Thrown after `--repair-fts` ran `createSearchFTSIndexes` and then `verifySearchFTSIndexes` still found indexes missing. The repair sweep now rebuilds every table it can before reporting, so the message includes per-index build-failure reasons (via `summarizeFtsIndexBuildFailures`) when `repairFailures` is non-empty. This distinguishes 'the rebuild itself reported why it failed' from a silent absence.

Source

Thrown at gitnexus/src/core/run-analyze.ts:1217

      const repairFailures = await createSearchFTSIndexes({
        onIndexStart: options.verbose
          ? (table, indexName) => log(`FTS: creating ${table}.${indexName}`)
          : undefined,
        onIndexReady: options.verbose
          ? (table, indexName) => log(`FTS: ready ${table}.${indexName}`)
          : undefined,
      });
      const missing = await verifySearchFTSIndexes(executeQuery);
      if (missing.length > 0) {
        // #2889: name WHY each index is missing when the build itself said so.
        // Repair now rebuilds every table it can before reporting, so the tables
        // absent from this list were genuinely repaired even on a failed run —
        // previously the first failure aborted the sweep and the message could
        // only ever list "missing", never a reason. Same sentence the analyze
        // degrade path prints, so one failure does not read two ways.
        const reasons =
          repairFailures.length > 0 ? ` ${summarizeFtsIndexBuildFailures(repairFailures)}.` : '';
        throw new Error(
          `FTS repair failed - missing indexes after rebuild: ${missing.join(', ')}.${reasons} ` +
            'Run `gitnexus analyze --force` to perform a full graph+FTS rebuild; ' +
            'if that also fails, verify FTS extension availability via `gitnexus doctor`.',
        );
      }
      await ensureGitNexusIgnored(repoPath);
      // #2767: stamp ONLY capabilities.fts so a long-lived MCP session's
      // ensureInitialized() has an explicit, correctly-scoped signal that FTS
      // changed — indexedAt/lastCommit/runnerIdentity/stats are copied through
      // untouched (see the "must not claim a new analyzer identity" comment
      // below). capabilities is forensic/no-programmatic-readers-until-now, so
      // graph/vectorSearch are backfilled with conservative, honest defaults
      // when a legacy meta.json predates this field entirely — repair-fts
      // never touched them and cannot claim a capability it did not verify.
      // Best-effort: a write failure must not turn an already-successful FTS
      // rebuild into a reported repair failure.
      try {
        // Re-read the on-disk meta immediately before writing, rather than

View on GitHub (pinned to d540b00184)

Solutions

  1. Run `gitnexus analyze --force` for a full graph + FTS rebuild from scratch.
  2. If `--force` also fails, run `gitnexus doctor` to verify the FTS extension is healthy.
  3. Check available disk space — FTS index creation needs temporary space proportional to indexed content.
  4. If the build-failure reasons mention a specific stemmer/tokenizer, verify `GITNEXUS_FTS_STEMMER` is set to a value the installed extension supports.

Example fix

// before
gitnexus analyze --repair-fts
// error: FTS repair failed - missing indexes after rebuild: ...
// after
gitnexus analyze --force  // full rebuild of graph + FTS
gitnexus doctor           // verify FTS extension health
Defensive patterns

Strategy: try-catch

Validate before calling

// After repair, verify indexes before reporting success (the repair path already does this internally):
import { verifySearchFTSIndexes } from './search/fts-indexes.js';
const missing = await verifySearchFTSIndexes(executeQuery);
if (missing.length > 0) {
  console.error(`Still missing: ${missing.join(', ')}. Run 'gitnexus analyze --force'.`);
}

Try / catch

try {
  await runAnalyze({ ...options, repairFts: true });
} catch (err) {
  if (err instanceof Error && err.message.includes('missing indexes after rebuild')) {
    console.error('Run `gitnexus analyze --force` for a full graph+FTS rebuild.');
  }
  throw err;
}

Prevention

When it happens

Trigger: `verifySearchFTSIndexes(executeQuery)` returns a non-empty `missing` array after `createSearchFTSIndexes` completed (possibly with partial failures). The FTS extension loaded but one or more `CREATE_FTS_INDEX` operations did not produce a usable index.

Common situations: A LadybugDB FTS schema mismatch after a version bump; a corrupt or nearly-full disk where the index creation partially succeeds; a tokenizer/stemmer value the installed extension rejects (validation passed but CREATE fails); a race where the DB was checkpointed mid-create.

Related errors


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