{"record":{"id":"947d515670e46fde","repo":"abhigyanpatwari/GitNexus","slug":"metadata-file-exists-but-is-unreadable-corrupt-le","errorCode":null,"errorMessage":"Metadata file exists but is unreadable/corrupt; leaving as-is (next successful analyze rewrites it)","messagePattern":"Metadata file exists but is unreadable/corrupt; leaving as-is \\(next successful analyze rewrites it\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/storage/repo-manager.ts","lineNumber":344,"sourceCode":"\n/**\n * Reconcile `gitnexus.json` and the legacy `meta.json` mirror in one\n * directory: whichever parses and is fresher (by `indexedAt`) wins and is\n * re-written to BOTH files via `saveMeta`. Never deletes anything.\n * Returns true when a write occurred.\n */\nconst reconcileMetaDir = async (dir: string): Promise<boolean> => {\n  const primary = await tryReadMetaFile(dir, INDEX_METADATA_FILE);\n  const legacy = await tryReadMetaFile(dir, LEGACY_METADATA_FILE);\n\n  if (!primary && !legacy) {\n    // Fresh directory (neither file) is a silent no-op; a file that exists\n    // but doesn't parse deserves a warning — loadMeta will treat it as \"no\n    // prior index\" and the next successful saveMeta self-heals it.\n    for (const filename of [INDEX_METADATA_FILE, LEGACY_METADATA_FILE]) {\n      try {\n        await fs.access(path.join(dir, filename));\n        logger.warn(\n          { dir, filename },\n          'Metadata file exists but is unreadable/corrupt; leaving as-is (next successful analyze rewrites it)',\n        );\n      } catch {\n        // absent — expected for a fresh directory\n      }\n    }\n    return false;\n  }\n\n  if (primary && legacy) {\n    if (JSON.stringify(primary) === JSON.stringify(legacy)) return false; // converged\n    // Both parse but differ — the fresher one wins (an older binary may have\n    // re-analyzed and written only meta.json AFTER gitnexus.json was created;\n    // blind-preferring the primary would permanently shadow that fresher\n    // state, silently certifying a stale index as up to date).\n    const winner = metaTimestamp(legacy) > metaTimestamp(primary) ? legacy : primary;\n    await saveMeta(dir, winner);","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/storage/repo-manager.ts#L326-L362","documentation":"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.","triggerScenarios":"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).","commonSituations":"Process killed during finalization; power loss mid-write; someone hand-edited or pretty-printed the metadata; empty file left by a full disk.","solutions":["Simply run analyze again: a successful run rewrites the metadata and clears the condition","Or delete the corrupt metadata file if you want the warning gone before the next run","No manual JSON repair is needed or expected — loadMeta already treats it as no prior index"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before trusting 'no prior index', check whether a metadata file exists:\n// present-but-unparseable is corruption that the next successful analyze heals.\ntry {\n  await fs.access(path.join(dir, INDEX_METADATA_FILE));\n  // exists while loadMeta returned nothing => expect this warning + full re-analysis\n} catch {\n  // absent — genuinely fresh directory, no warning expected\n}","typeGuard":null,"tryCatchPattern":"let meta;\ntry {\n  meta = await loadMeta(storagePath);\n} catch {\n  // unreadable/corrupt metadata behaves as 'no prior index';\n  // re-run analyze — a successful saveMeta rewrites (self-heals) it.\n  meta = undefined;\n}","preventionTips":["Do not hand-edit metadata JSON files","Let successful analyze runs self-heal corrupt metadata instead of manual surgery","A zero-byte metadata file after a crash is expected to warn exactly once"],"tags":["storage","metadata","corruption","self-healing","json"],"backgroundTag":"corrupt-metadata-file","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}