From 689f79acc1f7f86184a04ca9d853fef3820a31df Mon Sep 17 00:00:00 2001 From: henry Date: Fri, 22 May 2026 16:57:49 +0800 Subject: [PATCH] fix(analyze): make FTS index creation non-fatal during analyze When the LadybugDB FTS extension cannot be loaded (e.g. macOS 12 where libc++ lacks std::to_chars(double), or container environments without the native extension), `gitnexus analyze --embeddings` fails at 85% and aborts before embedding generation can run. This is inconsistent with the MCP server's behavior: pool-adapter.ts already treats FTS load failure as a graceful degradation (ftsLoaded = false, BM25 search degrades, other features continue). Change: wrap createSearchFTSIndexes() in try/catch so that: - FTS creation failure logs a warning instead of throwing - Embedding generation (Phase 4) proceeds normally - `--repair-fts` remains available for explicit FTS retry - BM25 keyword search degrades gracefully (same as MCP read path) Affected users: macOS 12 (Monterey), any platform where the FTS extension binary references symbols missing from the system libc++. --- gitnexus/src/core/run-analyze.ts | 37 +++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/gitnexus/src/core/run-analyze.ts b/gitnexus/src/core/run-analyze.ts index 79601a9a2..d18185824 100644 --- a/gitnexus/src/core/run-analyze.ts +++ b/gitnexus/src/core/run-analyze.ts @@ -669,22 +669,29 @@ export async function runFullAnalysis( // ── Phase 3: FTS (85–90%) ───────────────────────────────────────── progress('fts', 85, 'Creating search indexes...'); - 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 missingIndexNames = await verifySearchFTSIndexes(executeQuery); - if (missingIndexNames.length > 0) { - throw new Error( - `FTS verification failed - missing indexes after analyze: ${missingIndexNames.join(', ')}. ` + - 'Check FTS extension availability, then retry `gitnexus analyze --force` for a full rebuild.', - ); + try { + 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 missingIndexNames = await verifySearchFTSIndexes(executeQuery); + if (missingIndexNames.length > 0) { + log( + `⚠️ FTS verification warning - missing indexes: ${missingIndexNames.join(', ')}. ` + + 'BM25 keyword search will be degraded. Upgrade macOS or run on a compatible platform to enable FTS.', + ); + } else { + progress('fts', 90, 'Search indexes ready'); + } + } catch (ftsErr: unknown) { + const ftsMsg = ftsErr instanceof Error ? ftsErr.message : String(ftsErr); + log(`⚠️ FTS creation skipped (non-fatal): ${ftsMsg}`); + progress('fts', 90, 'Search indexes skipped (FTS unavailable)'); } - progress('fts', 90, 'Search indexes ready'); // ── Phase 3.5: Re-insert cached embeddings ──────────────────────── // Runs on BOTH the full-rebuild path and the incremental path: