abhigyanpatwari/GitNexus · error · Error
GitNexus: unable to acquire init lock after ${INIT_LOCK_MAX_
Error message
GitNexus: unable to acquire init lock after ${INIT_LOCK_MAX_ATTEMPTS} attempts — another gitnexus process may be initializing the same database (${lockPath}) What it means
Thrown by `acquireInitLock` after `INIT_LOCK_MAX_ATTEMPTS` (6) failed attempts to create the exclusive init lock file via `O_CREAT | O_EXCL`. Between attempts it tries to break a stale lock and waits `INIT_LOCK_RETRY_DELAY_MS` (500ms) when a live process holds it. The lock serializes cross-process DB initialization; if a real concurrent gitnexus process is initializing the same database, the lock legitimately stays held and this error names the lock path so the operator can identify the contention.
Source
Thrown at gitnexus/src/core/lbug/lbug-adapter.ts:438
logger.warn(
`GitNexus: failed to release init lock (${code ?? 'UNKNOWN'}): ${summarizeError(err)}`,
);
}
}
};
} catch (err) {
if ((err as NodeJS.ErrnoException)?.code !== 'EEXIST') {
throw err; // Unexpected error — propagate immediately
}
// Lock file exists — check if it's stale
const broken = await tryBreakStaleLock(lockPath);
if (broken && attempt < INIT_LOCK_MAX_ATTEMPTS) {
continue; // Stale lock removed — retry immediately
}
if (attempt === INIT_LOCK_MAX_ATTEMPTS) {
throw new Error(
`GitNexus: unable to acquire init lock after ${INIT_LOCK_MAX_ATTEMPTS} attempts — ` +
`another gitnexus process may be initializing the same database (${lockPath})`,
);
}
// Live process holds the lock — wait and retry
await new Promise((resolve) => setTimeout(resolve, INIT_LOCK_RETRY_DELAY_MS));
}
}
// Unreachable — loop always throws or returns
throw new Error('GitNexus: init lock acquisition failed unexpectedly');
};
/** Exported for testing — returns the lock file path for a given dbPath. */
export const _initLockPathForTest = initLockPath;
const runWithSessionLock = async <T>(operation: () => Promise<T>): Promise<T> => {View on GitHub (pinned to d540b00184)
Solutions
- Stop the other concurrent gitnexus process (serve/MCP/another analyze) using this repository, then retry.
- If no other process is running, inspect the lock file at the reported `lockPath` — its JSON payload names a PID; verify that PID is genuinely dead and remove the lock file if so.
- Wait a few seconds and retry — the 6x500ms budget may simply have been too short for a legitimately-finishing concurrent init.
- Avoid running `analyze` and `serve` against the same repo simultaneously.
Defensive patterns
Strategy: retry
Type guard
function isInitLockError(err): boolean {
return /unable to acquire init lock after \d+ attempts/i.test(
err instanceof Error ? err.message : String(err),
);
} Try / catch
// The lock holder usually finishes quickly; retry once after a short delay,
// after confirming no concurrent process is intentionally running.
for (let attempt = 0; attempt < 2; attempt++) {
try {
await initLbug(dbPath);
break;
} catch (err) {
if (/unable to acquire init lock/i.test(err.message) && attempt === 0) {
await new Promise(r => setTimeout(r, 1000));
continue;
}
throw err;
}
} Prevention
- Do not run analyze and serve/MCP against the same repo at the same time.
- In cron, use a process-level lock or stagger schedules to avoid overlap.
- If a lock is stale (holder PID dead), gitnexus auto-breaks it; only manually remove it if the PID is confirmed dead.
When it happens
Trigger: Two gitnexus processes (e.g. `gitnexus analyze` and `gitnexus serve`, or an MCP server) initializing the same database concurrently such that the lock file remains held for the full ~3s retry window; or a live (non-stale) lock that `tryBreakStaleLock` correctly refuses to remove.
Common situations: An editor MCP server and a CLI analyze hitting the same repo at once; a cron job overlapping a manual run; a previous process that crashed but left a lock the staleness check still considers live (e.g. its PID is reused).
Related errors
- Circuit '${key}' is open; retry in ${Math.ceil(halfOpenRetry
- Analyzer build changed while its identity was being computed
- Analyzer dependency runtime changed while its identity was b
- Analyzer build or dependency runtime changed while its ident
- Analyzer build or dependency runtime changed during analysis
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/56d2cda559f9234a.
Report an issue: GitHub.