{"record":{"id":"d265636af095d332","repo":"abhigyanpatwari/GitNexus","slug":"gitnexus-manual-wal-checkpoint-failed-after-retri","errorCode":null,"errorMessage":"GitNexus: manual WAL checkpoint failed after retries","messagePattern":"GitNexus: manual WAL checkpoint failed after retries","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/lbug/wal-checkpoint-driver.ts","lineNumber":191,"sourceCode":"  const tick = async (): Promise<void> => {\n    if (stopped) return;\n    // Reentrancy guard: setInterval keeps firing on its fixed cadence even when\n    // the previous checkpoint has not settled (a CHECKPOINT can outlast the\n    // period during a large `--pdg` writeback). Without this, each overdue tick\n    // would queue another CHECKPOINT — they now serialize on the connection lock\n    // (lbug-adapter `withConnLock`), but letting them pile up is still pointless\n    // work and widens the window for a backlog at stop(). Skip while one is in\n    // flight; the next tick covers any WAL accumulated in the meantime.\n    if (inflight) return;\n    inflight = runCheckpointWithRetry()\n      .then(() => undefined)\n      .catch((err) => {\n        // The retry budget exhausted. The caller's surrounding write\n        // will see the same engine error on its next operation and the\n        // `analyzeCommand` catch block will emit the recovery hint.\n        // Logging here keeps the operator-visible trail without\n        // double-logging the user-facing message.\n        logger.warn(\n          { err: err instanceof Error ? err.message : String(err) },\n          'GitNexus: manual WAL checkpoint failed after retries',\n        );\n      });\n    try {\n      await inflight;\n    } finally {\n      inflight = null;\n    }\n  };\n\n  const handle = setInterval(() => {\n    // Fire-and-forget: setInterval cannot await directly. The next tick\n    // is guarded by `stopped` and the `inflight` reference.\n    void tick();\n  }, periodMs);\n  // `setInterval` returned by Node is a `Timeout` object with `.unref()`\n  // so a hung driver never prevents process exit.","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/core/lbug/wal-checkpoint-driver.ts#L173-L209","documentation":"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.","triggerScenarios":"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.","commonSituations":"`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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Reduce contention before the write that triggers checkpoints:\n// pause MCP/serve traffic, or run analyze in an exclusive window\nif (serveTrafficActive()) await pauseServeOrScheduleAnalyze();","typeGuard":null,"tryCatchPattern":"try {\n  await runCheckpointWithRetry(); // the driver's own budget\n} catch (err) {\n  // matches the driver: let the surrounding write surface the engine error +\n  // analyzeCommand's recovery hint; retry after clearing long-running readers\n  await clearReaders();\n  await runCheckpointWithRetry();\n}","preventionTips":["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."],"tags":["ladybugdb","wal","checkpoint","ebusy","concurrency","retry-exhausted"],"backgroundTag":"wal-checkpoint-failed","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}