abhigyanpatwari/GitNexus · warning

Metadata file exists but is unreadable/corrupt; leaving as-i

Error message

Metadata file exists but is unreadable/corrupt; leaving as-is (next successful analyze rewrites it)

What it means

reconcileMetaDir probes the storage dir for the primary and legacy metadata files. If neither parses (tryReadMetaFile failed for both) but fs.access proves a file exists on disk, this warning fires: loadMeta will behave as if there were no prior index, and the next successful analyze rewrites the file (self-heal). It deliberately leaves the corrupt file as-is rather than attempting a destructive repair.

Source

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

/**
 * Reconcile `gitnexus.json` and the legacy `meta.json` mirror in one
 * directory: whichever parses and is fresher (by `indexedAt`) wins and is
 * re-written to BOTH files via `saveMeta`. Never deletes anything.
 * Returns true when a write occurred.
 */
const reconcileMetaDir = async (dir: string): Promise<boolean> => {
  const primary = await tryReadMetaFile(dir, INDEX_METADATA_FILE);
  const legacy = await tryReadMetaFile(dir, LEGACY_METADATA_FILE);

  if (!primary && !legacy) {
    // Fresh directory (neither file) is a silent no-op; a file that exists
    // but doesn't parse deserves a warning — loadMeta will treat it as "no
    // prior index" and the next successful saveMeta self-heals it.
    for (const filename of [INDEX_METADATA_FILE, LEGACY_METADATA_FILE]) {
      try {
        await fs.access(path.join(dir, filename));
        logger.warn(
          { dir, filename },
          'Metadata file exists but is unreadable/corrupt; leaving as-is (next successful analyze rewrites it)',
        );
      } catch {
        // absent — expected for a fresh directory
      }
    }
    return false;
  }

  if (primary && legacy) {
    if (JSON.stringify(primary) === JSON.stringify(legacy)) return false; // converged
    // Both parse but differ — the fresher one wins (an older binary may have
    // re-analyzed and written only meta.json AFTER gitnexus.json was created;
    // blind-preferring the primary would permanently shadow that fresher
    // state, silently certifying a stale index as up to date).
    const winner = metaTimestamp(legacy) > metaTimestamp(primary) ? legacy : primary;
    await saveMeta(dir, winner);

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Simply run analyze again: a successful run rewrites the metadata and clears the condition
  2. Or delete the corrupt metadata file if you want the warning gone before the next run
  3. No manual JSON repair is needed or expected — loadMeta already treats it as no prior index
Defensive patterns

Strategy: retry

Validate before calling

// Before trusting 'no prior index', check whether a metadata file exists:
// present-but-unparseable is corruption that the next successful analyze heals.
try {
  await fs.access(path.join(dir, INDEX_METADATA_FILE));
  // exists while loadMeta returned nothing => expect this warning + full re-analysis
} catch {
  // absent — genuinely fresh directory, no warning expected
}

Try / catch

let meta;
try {
  meta = await loadMeta(storagePath);
} catch {
  // unreadable/corrupt metadata behaves as 'no prior index';
  // re-run analyze — a successful saveMeta rewrites (self-heals) it.
  meta = undefined;
}

Prevention

When it happens

Trigger: A truncated or invalid-JSON index metadata file in the storage dir: analyze killed mid-write, a zero-byte file after disk-full or power loss, or manual editing that broke the JSON. The warning fires per existing file (primary and legacy are each probed).

Common situations: Process killed during finalization; power loss mid-write; someone hand-edited or pretty-printed the metadata; empty file left by a full disk.

Related errors


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