abhigyanpatwari/GitNexus · error · AnalysisNotFinalizedError

Analysis did not finalize for ${repoPath}: ${INDEX_METADATA_

Error message

Analysis did not finalize for ${repoPath}: ${INDEX_METADATA_FILE} was not written to ${path.join(storagePath, INDEX_METADATA_FILE)}. The on-disk index is incomplete and was not registered. Re-run "gitnexus analyze" — if the problem persists, inspect ${storagePath} for a stale lbug.wal that signals an aborted write.

What it means

After analyze writes an index, assertAnalysisFinalized verifies the finality artifacts before the run is considered done. This variant ('meta'): gitnexus.json (INDEX_METADATA_FILE) was never written into the repo's .gitnexus storage path — the analysis crashed or was interrupted before finalization, so the on-disk index is incomplete and deliberately was not registered.

Source

Thrown at gitnexus/src/storage/repo-manager.ts:1204

 *      (the primary metadata file; the legacy `meta.json` mirror is not
 *      sufficient — a finalized analyze always writes the primary).
 *   2. The global registry (`getGlobalRegistryPath()`) must contain an
 *      entry whose canonical path matches `repoPath`.
 *
 * Throws {@link AnalysisNotFinalizedError} on the first failure with the
 * specific missing artifact. Pure read — does not mutate disk state.
 *
 * Callers must skip this assertion on the `alreadyUpToDate` early-return
 * path, where the rebuild was deliberately not run.
 */
export const assertAnalysisFinalized = async (repoPath: string): Promise<void> => {
  const resolved = path.resolve(repoPath);
  const { storagePath, metaPath } = getStoragePaths(resolved);

  try {
    await fs.access(metaPath);
  } catch {
    throw new AnalysisNotFinalizedError(resolved, storagePath, 'meta', getGlobalRegistryPath());
  }

  if (!(await isRepoRegistered(resolved))) {
    throw new AnalysisNotFinalizedError(
      resolved,
      storagePath,
      'registry-entry',
      getGlobalRegistryPath(),
    );
  }
};

/**
 * Thrown by {@link assertSafeStoragePath} when a registry entry's
 * `storagePath` does NOT point at the expected `<entry.path>/.gitnexus`
 * subfolder. CLI destructive commands (`remove`, `clean --all`) should
 * catch this and exit non-zero without deleting anything — the usual
 * cause is a corrupted or hand-edited `~/.gitnexus/registry.json`, and

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Re-run gitnexus analyze — the pipeline rebuilds and re-seals the index
  2. If it persists, inspect <repo>/.gitnexus for a stale lbug.wal (aborted-write signal) and clean the storage (gitnexus clean) before re-indexing
  3. Free disk space and raise memory/CI timeouts so the run can complete
  4. Check for concurrent analyze runs that raced the write (see the index-lock timeout errors)
Defensive patterns

Strategy: retry

Validate before calling

import fs from 'node:fs';
import path from 'node:path';
function indexFinalized(repo: string): boolean {
  return fs.existsSync(path.join(repo, '.gitnexus', 'gitnexus.json'));
}

Try / catch

try {
  await runAnalyze(repo);
} catch (e) {
  if (e?.name === 'AnalysisNotFinalizedError' && e.kind === 'meta') {
    await cleanStorage(repo); // removes stale lbug.wal from the aborted write
    return runAnalyze(repo); // one clean rebuild
  }
  throw e;
}

Prevention

When it happens

Trigger: analyze is killed (OOM, SIGKILL, CI timeout) between writing index data and sealing metadata; a LadybugDB write aborted leaving a stale lbug.wal; disk-full blocking the final metadata write.

Common situations: Large repos killed near the end of indexing; container memory limits; full disks; machines sleeping mid-run.

Related errors


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