{"record":{"id":"c570c8cfd70d7371","repo":"abhigyanpatwari/GitNexus","slug":"ladybugdb-wal-corruption-detected-for-repoid-r","errorCode":null,"errorMessage":"LadybugDB WAL corruption detected for ${repoId}. Run `gitnexus analyze` to rebuild the index. (quarantine failed)","messagePattern":"LadybugDB WAL corruption detected for (.+?)\\. Run `gitnexus analyze` to rebuild the index\\. \\(quarantine failed\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"gitnexus/src/core/lbug/pool-adapter.ts","lineNumber":636,"sourceCode":"  } catch (err) {\n    if (db) await db.close().catch(() => {});\n    throw err;\n  } finally {\n    restoreStdout();\n  }\n}\n\n/**\n * Quarantine the .wal file and retry opening the database.\n * Used when the initial open fails with a WAL corruption error.\n */\nasync function tryQuarantineAndReopen(dbPath: string, repoId: string): Promise<lbug.Database> {\n  const walPath = dbPath + '.wal';\n  const quarantineName = `${walPath}.corrupt.${Date.now()}-${Math.random().toString(36).slice(2)}`;\n  try {\n    await fs.rename(walPath, quarantineName);\n  } catch {\n    throw new Error(\n      `LadybugDB WAL corruption detected for ${repoId}. ` +\n        `Run \\`gitnexus analyze\\` to rebuild the index. (quarantine failed)`,\n    );\n  }\n  realStderrWrite(\n    `GitNexus: LadybugDB WAL quarantined for ${repoId}; graph may be stale. ` +\n      `Run \\`gitnexus analyze\\` to rebuild the index.\\n`,\n  );\n  return await openReadOnlyDatabase(dbPath);\n}\n\n/** Deduplicates concurrent initLbug calls for the same repoId */\nconst initPromises = new Map<string, Promise<void>>();\n\n/**\n * Initialize (or reuse) a Database + connection pool for a specific repo.\n * Retries on lock errors (e.g., when `gitnexus analyze` is running).\n *","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/lbug/pool-adapter.ts#L618-L654","documentation":"Thrown by tryQuarantineAndReopen when fs.rename of the .wal file to a quarantine name fails. This function is the WAL corruption recovery path: the initial DB open detected a corrupt WAL (matched by isWalCorruptionError), and the remedy is to rename the .wal aside so LadybugDB can open without replaying corrupt WAL records. If the rename itself fails (permission denied, file locked by another process, or the .wal file doesn't exist), quarantine is impossible and the error propagates. The quarantined WAL is named with a timestamp + random suffix.","triggerScenarios":"Opening a read-only LadybugDB database via the pool adapter when the WAL is corrupt and the quarantine rename of <dbPath>.wal fails — typically because another process holds an exclusive lock on the .wal file, the filesystem is read-only, or permissions prevent the rename. The recovery chain: openLbug fails with WAL corruption → tryQuarantineAndReopen → fs.rename throws → this error.","commonSituations":"A `gitnexus serve` or MCP process holds the .wal file open while a concurrent process tries to open the same DB read-only; read-only mounted filesystem that prevents rename; a crashed process that left the .wal file with restrictive permissions; Windows file locking where Defender or another process briefly holds the file.","solutions":["Stop all GitNexus processes (serve, MCP) that may hold the .wal file, then re-run `gitnexus analyze` to rebuild the index from scratch","Run `gitnexus analyze --force` to force a full rebuild — this recreates the DB and WAL cleanly","Check filesystem permissions on the .gitnexus/ storage directory — the GitNexus process needs read/write access","If on a read-only mount, remount read-write or point GitNexus storage to a writable location","Use `lsof <repo>.wal` to find and kill any process holding the file"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Verify the WAL file is writable before attempting quarantine\nimport { access, constants } from 'fs/promises';\nasync function canQuarantineWal(walPath: string): Promise<boolean> {\n  try {\n    await access(walPath, constants.W_OK);\n    return true;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const db = await tryQuarantineAndReopen(dbPath, repoId);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('quarantine failed')) {\n    // Stop all processes holding the WAL, then force rebuild\n    logger.error('WAL quarantine failed — stop all GitNexus processes and run analyze --force');\n  }\n  throw e;\n}","preventionTips":["Stop all GitNexus processes before running analyze to prevent WAL lock contention","On Windows, add antivirus exclusions for the .gitnexus/ directory","Ensure the storage directory is on a writable filesystem (not read-only mount)","Regularly run `gitnexus analyze` to keep the WAL checkpointed and small"],"tags":["ladybugdb","wal-corruption","quarantine","file-lock","pool-adapter"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}