abhigyanpatwari/GitNexus · warning
GitNexus: manual WAL checkpoint failed after retries
Error message
GitNexus: manual WAL checkpoint failed after retries
What it means
The periodic manual WAL checkpoint driver (runCheckpointWithRetry under withConnLock, with a bounded retry budget) exhausted its retries. The comment spells out the contract: the surrounding write will see the same engine error on its next operation, and analyzeCommand's catch block emits the user-facing recovery hint — this warn is the operator-visible trail without double-logging. Skips while a checkpoint is inflight so attempts do not pile up.
Source
Thrown at gitnexus/src/core/lbug/wal-checkpoint-driver.ts:191
const tick = async (): Promise<void> => {
if (stopped) return;
// Reentrancy guard: setInterval keeps firing on its fixed cadence even when
// the previous checkpoint has not settled (a CHECKPOINT can outlast the
// period during a large `--pdg` writeback). Without this, each overdue tick
// would queue another CHECKPOINT — they now serialize on the connection lock
// (lbug-adapter `withConnLock`), but letting them pile up is still pointless
// work and widens the window for a backlog at stop(). Skip while one is in
// flight; the next tick covers any WAL accumulated in the meantime.
if (inflight) return;
inflight = runCheckpointWithRetry()
.then(() => undefined)
.catch((err) => {
// The retry budget exhausted. The caller's surrounding write
// will see the same engine error on its next operation and the
// `analyzeCommand` catch block will emit the recovery hint.
// Logging here keeps the operator-visible trail without
// double-logging the user-facing message.
logger.warn(
{ err: err instanceof Error ? err.message : String(err) },
'GitNexus: manual WAL checkpoint failed after retries',
);
});
try {
await inflight;
} finally {
inflight = null;
}
};
const handle = setInterval(() => {
// Fire-and-forget: setInterval cannot await directly. The next tick
// is guarded by `stopped` and the `inflight` reference.
void tick();
}, periodMs);
// `setInterval` returned by Node is a `Timeout` object with `.unref()`
// so a hung driver never prevents process exit.View on GitHub (pinned to aac7515d2a)
Solutions
- Stop the concurrent reader (serve/MCP queries) during indexing so the checkpoint can complete, then re-run.
- Watch for the analyzeCommand recovery hint that follows — it names the suggested action for the underlying engine error.
- Add antivirus exclusions for the .gitnexus directory (WAL + shadow files).
- If WAL corruption is the cause, rebuild the DB from scratch rather than retrying into a corrupt WAL.
Defensive patterns
Strategy: retry
Validate before calling
// Reduce contention before the write that triggers checkpoints: // pause MCP/serve traffic, or run analyze in an exclusive window if (serveTrafficActive()) await pauseServeOrScheduleAnalyze();
Try / catch
try {
await runCheckpointWithRetry(); // the driver's own budget
} catch (err) {
// matches the driver: let the surrounding write surface the engine error +
// analyzeCommand's recovery hint; retry after clearing long-running readers
await clearReaders();
await runCheckpointWithRetry();
} Prevention
- Do not run long serve queries while analyze writes to the same DB.
- Exclude WAL/shadow files from antivirus on Windows.
- Watch WAL file growth — sustained growth despite interval ticks means checkpoints keep failing.
When it happens
Trigger: The interval-driven checkpoint fires after writes; CHECKPOINT keeps failing across the whole retry budget — long-running readers pinning the WAL, EBUSY from concurrent access, antivirus interference, or WAL corruption. The next tick would retry, but the failure means WAL growth continues until then.
Common situations: `gitnexus serve` answering long queries while analyze writes (readers block checkpoint); Windows Defender scanning WAL files; DBs on network volumes; large indexes with heavy churn between ticks.
Related errors
- LadybugDB checkpoint sidecar is missing for ${dbPath}. Rebui
- LadybugDB unavailable for ${repoId}. Another process may be
- ${source} must be a string.
- LadybugDB checkpoint sidecar is missing for ${dbPath}. Rebui
- GitNexus: failed to reclaim missing-shadow WAL quarantines:
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/d265636af095d332.
Report an issue: GitHub.