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 thanView on GitHub (pinned to d540b00184)
Solutions
- Run `gitnexus analyze --force` for a full graph + FTS rebuild from scratch.
- If `--force` also fails, run `gitnexus doctor` to verify the FTS extension is healthy.
- Check available disk space — FTS index creation needs temporary space proportional to indexed content.
- 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
- Keep the LadybugDB FTS extension version aligned with the GitNexus version to avoid schema mismatches.
- Ensure adequate disk space before running analyze — FTS creation is space-intensive.
- Run `gitnexus doctor` periodically to catch extension health issues early.
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
- Cannot repair FTS indexes: the index is mid-incremental-reco
- Cannot repair FTS indexes: graph store at ${lbugPath} is mis
- Cannot repair FTS indexes: graph store at ${lbugPath} is ${f
- Search index build failed with an integrity error and the an
- LadybugDB checkpoint sidecar is missing for ${dbPath}. Rebui
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/b973c68114516774.
Report an issue: GitHub.