abhigyanpatwari/GitNexus · error
LadybugDB unavailable for
Error message
LadybugDB unavailable for ${repoId}. Another process may be rebuilding the index. Retry later. (${lastError?.message || 'unknown error'}) What it means
doInitLbug (gitnexus/src/core/lbug/pool-adapter.ts:794): after LOCK_RETRY_ATTEMPTS lock-busy retries — or an open failure that is neither WAL corruption, sidecar-classified, nor lock-busy — no shared Database could be opened. The trailing parenthesized message is the last underlying error; the typical cause is a concurrent writer holding the database lock.
Solutions
- Retry once the concurrent analyze finishes — the message says exactly that
- Stagger schedules so serve/MCP startup does not race analyze on the same repo
- Read the trailing lastError: if it is not lock-shaped, fix that underlying issue (path, permissions)
- Never write from MCP/serve — keep writers to analyze so the read-only pool rarely contends
Defensive patterns
Strategy: retry
Validate before calling
// before opening, check whether another writer holds the index (lock file present + alive)
import { readFile } from 'node:fs/promises';
const lockPid = await readFile(`${dbPath}.lock`, 'utf8').then(
(s) => s.trim(),
() => '',
);
if (lockPid && (await isProcessAlive(Number(lockPid)))) {
throw new Error('analyze in progress — defer pool init');
} Type guard
const isLbugUnavailable = (e: unknown): boolean =>
e instanceof Error && e.message.startsWith('LadybugDB unavailable for'); Try / catch
let lastErr: unknown;
for (let attempt = 0; attempt < 5; attempt++) {
try {
await initLbug(repoId, dbPath);
break;
} catch (e) {
lastErr = e;
if (!isLbugUnavailable(e)) throw e;
await sleep(10_000 * (attempt + 1)); // back off while the rebuild finishes
}
}
if (lastErr) throw lastErr; Prevention
- Schedule serve/MCP startup to wait for a running analyze instead of racing it
- Keep exactly one writer (analyze) per repository; all readers use the read-only pool
- Read the trailing lastError — non-lock causes need different fixes than waiting
When it happens
Trigger: initLbug while `gitnexus analyze` (or another serve/MCP instance in write mode) holds the database lock longer than the retry budget; or any open error with no dedicated recovery path (the lastError text says which).
Common situations: Starting an MCP session or serve during a long incremental analyze; several CI jobs opening the same mounted storage simultaneously.
Related errors
- GitNexus: manual WAL checkpoint failed after retries
- Batch execution failed for rows
- Cannot verify acquisition/reclaim guard ownership
- Connection pool integrity error: expected
- Failed to remove the LadybugDB index files — still present…
AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20).
Data as JSON: /api/errors/806822f443537509.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/lbug/pool-adapter.ts:799
if (
lastError.message.startsWith('LadybugDB checkpoint sidecar is missing') ||
lastError.message.startsWith('LadybugDB checkpoint sidecar is present but unreachable') ||
lastError.message.startsWith('GitNexus could not move the LadybugDB WAL sidecar') ||
isMissingShadowSidecarError(lastError)
) {
throw lastError;
}
const isLockError =
lastError.message.includes('Could not set lock') ||
/\block(\b|ed|ing)/i.test(lastError.message);
if (!isLockError || attempt === LOCK_RETRY_ATTEMPTS) break;
await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_DELAY_MS * attempt));
}
}
if (!shared) {
throw new Error(
`LadybugDB unavailable for ${repoId}. Another process may be rebuilding the index. ` +
`Retry later. (${lastError?.message || 'unknown error'})`,
);
}
}
shared.refCount++;
const db = shared.db;
// Pre-create the full pool upfront so createConnection() (which silences
// stdout) is never called lazily during active query execution.
// Mark preWarmActive so the watchdog timer doesn't interfere.
preWarmActive = true;
const available: lbug.Connection[] = [];
try {
for (let i = 0; i < MAX_CONNS_PER_REPO; i++) {
available.push(createConnection(db));
}View on GitHub (pinned to 52924ef12c)