{"record":{"id":"b41a9672f6e3a016","repo":"abhigyanpatwari/GitNexus","slug":"ladybugdb-wal-corruption-detected-at-dbpath-wa","errorCode":null,"errorMessage":"LadybugDB WAL corruption detected at ${dbPath}. WAL corruption detected. Run `gitnexus analyze --force` to rebuild the index.\n  Original error: ${msg.slice(0, 200)}","messagePattern":"LadybugDB WAL corruption detected at (.+?)\\. WAL corruption detected\\. Run `gitnexus analyze --force` to rebuild the index\\.\n  Original error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"gitnexus/src/core/lbug/lbug-adapter.ts","lineNumber":733,"sourceCode":"      //   - \"already exists\": expected idempotent re-create on existing DBs\n      //   - \"could not set lock on file\": LadybugDB v0.18.0 emits this on\n      //     Windows when CREATE NODE TABLE runs against a path that was\n      //     just opened (the WAL handle from a fresh Database briefly\n      //     contests the table's first-write lock). The table is created\n      //     anyway and any genuine cross-process lock contention surfaces\n      //     on the next operation via withLbugDb's retry. Logging it here\n      //     would just be noise in CI.\n      //\n      // WAL corruption: the first DDL write after DB open triggers WAL\n      // replay — if the WAL file was left in a corrupt state by an\n      // interrupted previous run, the native engine throws here. Rather\n      // than logging a WARN and continuing in a broken state, close the\n      // DB cleanly and surface an actionable error so the caller (serve,\n      // MCP, analyze) can exit with a clear recovery message.\n      if (isWalCorruptionError(err)) {\n        await safeClose();\n        resetOpenConnectionState();\n        throw new Error(\n          `LadybugDB WAL corruption detected at ${dbPath}. ${WAL_RECOVERY_SUGGESTION}\\n` +\n            `  Original error: ${msg.slice(0, 200)}`,\n        );\n      }\n      if (isStorageVersionMismatchError(err)) {\n        await safeClose();\n        resetOpenConnectionState();\n        throwIfStorageVersionMismatch(err);\n      }\n      if (!msg.includes('already exists') && !isDbBusyError(err) && !isReadOnlyDbError(err)) {\n        logger.warn(`⚠️ Schema creation warning: ${msg.slice(0, 120)}`);\n      }\n    }\n  }\n\n  return null;\n};\n","sourceCodeStart":715,"sourceCodeEnd":751,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/core/lbug/lbug-adapter.ts#L715-L751","documentation":"lbug-adapter.ts line 711 (schema creation): the first DDL write after opening the database triggers WAL replay; if the previous run was interrupted leaving a corrupt WAL, the native engine throws (matched by WAL_CORRUPTION_RE: 'corrupt(ed) wal', 'invalid wal record', 'wal…corrupt', 'checksum…wal'). Rather than logging a warning and continuing broken, the connection is closed cleanly, open-connection state is reset, and WAL_RECOVERY_SUGGESTION is surfaced: rebuild with `gitnexus analyze --force`.","triggerScenarios":"A prior analyze/query was killed mid-write (OOM kill, SIGKILL, power loss) leaving a torn WAL; the WAL was truncated by disk-full; then any later command that opens the DB and issues DDL (analyze, or a writable serve path).","commonSituations":"CI runners being OOM-killed or timing out mid-analyze; laptops sleeping/crashing during indexing; antivirus or sync tools (Dropbox/OneDrive) mutating files in the storage dir; disk-full incidents.","solutions":["Run `gitnexus analyze --force <repo-path>` to discard the corrupt WAL and rebuild the index","If corruption recurs, find the interrupting cause: raise CI timeouts/memory, stop concurrent writers, add AV/sync exclusions for the storage dir","Verify disk health if WAL corruption appears without any interrupted run"],"exampleFix":"# before\n$ gitnexus serve   # 'WAL corruption detected' on open\n# after\n$ gitnexus analyze --force /path/to/repo\ngitnexus serve","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await withLbugDb(dbPath, run);\n} catch (err) {\n  const msg = err instanceof Error ? err.message : String(err);\n  if (/corrupt(ed)?\\s+wal|invalid\\s+wal\\s+record|wal.*corrupt|checksum.*wal/i.test(msg)) {\n    // rebuild deterministically: `gitnexus analyze --force <repo>`, then retry the original operation once\n  }\n  throw err;\n}","preventionTips":["Prevent interrupted writes: give analyze enough memory/time in CI so it is never OOM-killed mid-write","Exclude the storage dir from antivirus and file-sync tools that can mutate or lock DB/WAL files","After any crash mid-analyze, run `gitnexus analyze --force` proactively before other commands touch the index"],"tags":["wal","ladybugdb","corruption","index","recovery","analyze"],"backgroundTag":"database-corruption","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}