abhigyanpatwari/GitNexus · critical
LadybugDB WAL corruption detected for
Error message
LadybugDB WAL corruption detected for ${repoId}. Run `gitnexus analyze` to rebuild the index. (quarantine failed) What it means
tryQuarantineAndReopen (gitnexus/src/core/lbug/pool-adapter.ts:636): the initial read-only open failed with a WAL-corruption-shaped engine error, and moving the .wal aside to a .corrupt.<timestamp> quarantine file also failed. Recovery is impossible in-process, so the caller is told to rebuild the index.
Solutions
- Run `gitnexus analyze` for that repo — a fresh build replaces the corrupted file family
- If analyze cannot clear it either, stop competing processes, fix permissions, or manually delete the <db>, .wal and .shadow files and re-analyze
- If WAL corruption recurs across rebuilds, test the disk (smartctl) — repeated corruption usually means failing hardware
Defensive patterns
Strategy: retry
Type guard
const isQuarantineFailedWalCorruption = (e: unknown): boolean =>
e instanceof Error &&
e.message.includes('WAL corruption detected') &&
e.message.includes('(quarantine failed)'); Try / catch
try {
await initLbug(repoId, dbPath);
} catch (e) {
if (isQuarantineFailedWalCorruption(e)) {
// automatic recovery is exhausted — rebuild the index, then retry
throw new Error('run gitnexus analyze to rebuild this index before serving it');
}
throw e;
} Prevention
- Ensure the storage directory is writable and unlocked so automatic WAL quarantine can work
- Avoid hard power-loss during writebacks; use graceful shutdown
- Recurring WAL corruption across rebuilds points at failing storage — test the disk
When it happens
Trigger: initLbug opening a repo whose .wal is corrupted (torn write, crash mid-checkpoint) while the quarantine rename fails — the file is locked, the volume is read-only, or the directory is not writable.
Common situations: Hard power-off during analyze writeback followed by a locked file (AV, another serve process); storage directory with wrong ownership after a user or container change.
Related errors
- LadybugDB WAL corruption detected for
- GitNexus could not move the LadybugDB WAL sidecar at
- LadybugDB checkpoint sidecar is missing for
- LadybugDB WAL corruption detected at
- Batch execution failed for rows
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-08-20).
Data as JSON: /api/errors/c570c8cfd70d7371.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/lbug/pool-adapter.ts:699
} catch (err) {
if (db) await db.close().catch(() => {});
throw err;
} finally {
restoreStdout();
}
}
/**
* Quarantine the .wal file and retry opening the database.
* Used when the initial open fails with a WAL corruption error.
*/
async function tryQuarantineAndReopen(dbPath: string, repoId: string): Promise<lbug.Database> {
const walPath = dbPath + '.wal';
const quarantineName = `${walPath}.corrupt.${Date.now()}-${Math.random().toString(36).slice(2)}`;
try {
await fs.rename(walPath, quarantineName);
} catch {
throw new Error(
`LadybugDB WAL corruption detected for ${repoId}. ` +
`Run \`gitnexus analyze\` to rebuild the index. (quarantine failed)`,
);
}
realStderrWrite(
`GitNexus: LadybugDB WAL quarantined for ${repoId}; graph may be stale. ` +
`Run \`gitnexus analyze\` to rebuild the index.\n`,
);
return await openReadOnlyDatabase(dbPath);
}
// Serializes pool mutations (evict / close / native open / register) across
// concurrent callers. Awaiting closeOne/evictLRU closes the race within a
// single call; this mutex makes those mutations mutually exclusive across
// repos so two inits cannot race each other's checkpoint.
let poolLock: Promise<unknown> = Promise.resolve();
function withPoolLock<T>(fn: () => Promise<T>): Promise<T> {
const run = poolLock.then(fn, fn);View on GitHub (pinned to ac9a4e9abd)