abhigyanpatwari/GitNexus · error

FTS extension unavailable - cannot create FTS index

Error message

FTS extension unavailable - cannot create FTS index ${tableName}.${indexName}. Run `gitnexus doctor` and ensure the LadybugDB FTS extension is installed and loadable on this machine.

What it means

createFTSIndex (gitnexus/src/core/lbug/lbug-adapter.ts:3109) refuses to run CREATE_FTS_INDEX when loadFTSExtension() returns false — the LadybugDB FTS extension binary could not be installed or loaded in this environment (missing file, wrong platform, missing runtime dependency such as OpenSSL or the VC++ runtime, or a blocked install). Creating the index without the extension is impossible, so the call fails with doctor guidance.

Solutions

  1. Run `gitnexus doctor` — it diagnoses and reports the extension state on this machine
  2. Ensure the machine can reach the LadybugDB extension server or pre-install the FTS extension into the cache, then retry
  3. Install the missing runtime dependency the load diagnosis names (OpenSSL / VC++ runtime) and retry
  4. If FTS is not needed in this environment, rebuild without it: gitnexus analyze --force

Example fix

// before — assumes FTS is available and throws when it is not
await createFTSIndex('CodeSymbol', 'fts_name', ['name']);

// after — probe first and degrade gracefully
if (!(await loadFTSExtension(undefined, { policy: 'load-only' }))) {
  logger.warn('FTS unavailable — search falls back to exact scan');
} else {
  await createFTSIndex('CodeSymbol', 'fts_name', ['name']);
}
Defensive patterns

Strategy: fallback

Validate before calling

// probe before creating FTS indexes; degrade instead of throwing
const ftsOk = await loadFTSExtension(undefined, { policy: 'load-only' });
if (!ftsOk) {
  logger.warn('FTS extension unavailable — using exact scan for search');
}

Type guard

const isFtsUnavailable = (e: unknown): boolean =>
  e instanceof Error && e.message.startsWith('FTS extension unavailable');

Try / catch

try {
  await createFTSIndex(tableName, indexName, properties);
} catch (e) {
  if (isFtsUnavailable(e)) {
    // fall back to the non-FTS search path rather than failing the analyze
    logger.warn(`skipping FTS index ${indexName}: ${e.message}`);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: First analyze on a machine where the FTS extension is not installed and auto-install cannot fetch it (offline, proxy-blocked, extension server unreachable), or the binary fails to load (missing OS dependency, wrong architecture); calling createFTSIndex/ensureFTSIndex before any successful load.

Common situations: Air-gapped CI containers; slim Docker images lacking the runtime libs the extension links against; a moved or corrupted extension cache directory; read-only HOME preventing INSTALL from writing.

Related errors


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

Appendix: source

Thrown at gitnexus/src/core/lbug/lbug-adapter.ts:3470

 * @param indexName - Name for the FTS index
 * @param properties - List of properties to index (e.g., ['name', 'code'])
 * @param stemmer - Stemming algorithm (default: 'porter')
 */
export const createFTSIndex = async (
  tableName: string,
  indexName: string,
  properties: string[],
  stemmer: string = DEFAULT_FTS_STEMMER,
): Promise<void> => {
  if (!conn) {
    throw new Error('LadybugDB not initialized. Call initLbug first.');
  }

  const key = ftsIndexKey(tableName, indexName);
  if (ensuredFTSIndexes.has(key)) return;

  if (!(await loadFTSExtension())) {
    throw new Error(
      `FTS extension unavailable - cannot create FTS index ${tableName}.${indexName}. ` +
        'Run `gitnexus doctor` and ensure the LadybugDB FTS extension is installed and loadable on this machine.',
    );
  }

  const propList = properties.map((p) => `'${p}'`).join(', ');
  const query = `CALL CREATE_FTS_INDEX('${tableName}', '${indexName}', [${propList}], stemmer := '${stemmer}')`;

  try {
    await queryAndDrain(conn, query);
    ensuredFTSIndexes.add(key);
  } catch (e: any) {
    if (e.message?.includes('already exists')) {
      ensuredFTSIndexes.add(key);
      return;
    }
    throw e;
  }

View on GitHub (pinned to ac9a4e9abd)