abhigyanpatwari/GitNexus · error · LbugWipeError
lbug-wipe-failed
lbug-wipe-failed
Error message
Cannot start dirty-state recovery — the interrupted run's LadybugDB sidecars could neither be moved aside nor removed:
What it means
When a previous analyze run died in a dirty state, GitNexus must move or delete the leftover LadybugDB sidecar files before it can start dirty-state recovery. If the quarantine/wipe of those files fails outright, it throws LbugWipeError (code `lbug-wipe-failed`) immediately rather than letting a later database open fail opaquely. The message carries the failed paths and lock guidance, and the CLI renders it with the `lbug-wipe-failed` recovery hint.
Solutions
- Identify and stop any process holding the repo's LadybugDB files (GitNexus MCP server, `gitnexus serve`, another analyze).
- Re-run the command once the lock is released — the wipe is retried at open time and should then succeed.
- If no other process exists, fix permissions on the `.gitnexus` storage directory so the files can be renamed/removed.
- As a last resort, run `gitnexus clean --lbug-sidecars` manually and then retry `gitnexus analyze`.
Example fix
// before: serve process left running in another terminal $ gitnexus analyze LbugWipeError: Cannot start dirty-state recovery — ... sidecars could neither be moved aside nor removed // after $ <kill the lingering `gitnexus serve`/MCP process> $ gitnexus analyze # recovery proceeds, sidecars quarantined
Defensive patterns
Strategy: retry
Validate before calling
// check for a live lock-holder before starting recovery
const { execSync } = require('child_process');
const holders = execSync(`lsof +D ${storageDir} 2>/dev/null || true`).toString().trim();
if (holders) throw new Error('Another process holds the index files; stop it before recovering.'); Try / catch
try {
await runFullAnalysis(opts);
} catch (e) {
if (e.code === 'lbug-wipe-failed') {
await stopGitNexusProcesses(repoPath); // stop MCP/serve holders
await runFullAnalysis(opts); // retry once lock is released
} else throw e;
} Prevention
- Shut down lingering `gitnexus serve`/MCP processes before recovery runs.
- Never analyze the same repository from two concurrent invocations.
- Ensure the `.gitnexus` storage directory is writable by the running user.
- On Windows/AV setups, exclude the storage directory from real-time file locking.
When it happens
Trigger: `runFullAnalysisInner` detects a dirty previous run and calls the sidecar wipe/quarantine step; the step reports entries in `failed` (files could be neither moved aside nor deleted) — almost always because another process (MCP server or `gitnexus serve`) holds the LadybugDB files open, or OS permissions deny the rename/unlink.
Common situations: Leftover `gitnexus serve` or MCP worker from an earlier session still holding the index; analyzing the same repo concurrently from two terminals; read-only or root-owned `.gitnexus` storage after a container/user switch; Windows file locks from an editor or antivirus scanning the WAL.
Related errors
- LadybugDB checkpoint sidecar is present but unreachable for
- Failed to remove the LadybugDB index files — still present…
- GitNexus could not move the LadybugDB WAL sidecar at
- GitNexus could not move the LadybugDB WAL sidecar at
- GitNexus: failed to release init lock
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/d30dc965c4d6c45b.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/run-analyze.ts:1705
'from the interrupted run (the file could not be moved aside, so its bytes were ' +
'removed — post-mortem forensics lost). Recovery proceeds with full embedding ' +
'preservation.',
);
}
if (failed.length > 0) {
// FIX 1 (this shipping review, replacing the tri-review 4669518496
// P2-3 drop-shape design): under a persistent lock the old drop-shape
// run derived its embedding mode as "drop", ran the WHOLE pipeline,
// and then died at the rebuild wipe on the very same handle — wasting
// minutes and zeroing embeddings on the way. A possibly-poisoned
// sidecar still sits next to the DB (any pre-wipe open would replay it
// and die), so failing here, in seconds, with the same actionable
// typed error the wipe would eventually throw is strictly better —
// and the CLI's LbugWipeError handler already renders it
// (recoveryHint 'lbug-wipe-failed'). The message is self-contained
// (headline + paths + lock guidance) because serve forwards only
// err.message over worker IPC.
throw new LbugWipeError(failed, {
headline:
"Cannot start dirty-state recovery — the interrupted run's LadybugDB sidecars " +
'could neither be moved aside nor removed:',
});
}
}
}
// ── pdg-mode flip forces full writeback (#2099 F1) ─────────────────
// The incremental writeback persists only changed-file nodes, so a pdg
// config differing from the one the DB rows were built under cannot be
// reconciled incrementally: off→on silently drops the freshly built CFG
// layer ("Incremental: changed=0", zero BasicBlock rows), on→off strands
// zombie blocks for unchanged files. MUST sit before the alreadyUpToDate
// fast path below — a clean-tree flip would otherwise early-return without
// running the pipeline at all. The notice is deliberately NOT gated on
// options.force: --skills implies force with no message of its own, and a
// mode change deserves a diagnostic regardless of why a rebuild happens.View on GitHub (pinned to ac9a4e9abd)