abhigyanpatwari/GitNexus · error

LadybugDB unavailable for ${repoId}. Another process may be

Error message

LadybugDB unavailable for ${repoId}. Another process may be rebuilding the index. Retry later. (${lastError?.message || 'unknown error'})

What it means

Thrown by doInitLbug after all lock-retry attempts are exhausted without successfully opening the database. The retry loop (LOCK_RETRY_ATTEMPTS=3, LOCK_RETRY_DELAY_MS=2000 with linear back-off) handles transient lock contention where another process briefly holds the DB lock; if all 3 attempts fail, the DB is genuinely locked by another process or the lock file is stale. The error includes the lastError message for diagnostics and advises retrying later.

Source

Thrown at gitnexus/src/core/lbug/pool-adapter.ts:794

        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 d540b00184)

Solutions

  1. Wait for the other GitNexus process to finish (check with `ps aux | grep gitnexus`), then retry
  2. If no process is running but the lock persists (stale lock), delete the .lock file in the .gitnexus/ storage directory and retry
  3. Run `gitnexus analyze --force` which acquires its own lock and will clear stale lock state
  4. Ensure only one GitNexus process accesses a given repository at a time — the pool adapter is read-only and cannot share with a concurrent writer
Defensive patterns

Strategy: retry

Validate before calling

// Check if another process holds the DB lock before initializing
import { access } from 'fs/promises';
// Best pre-check: look for running gitnexus processes
import { execSync } from 'child_process';
function gitnexusProcessesRunning(): boolean {
  try {
    const out = execSync('pgrep -f gitnexus', { encoding: 'utf8' });
    return out.trim().length > 0;
  } catch {
    return false;
  }
}

Try / catch

try {
  await doInitLbug(repoId, dbPath);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('LadybugDB unavailable')) {
    // Wait for the other process to finish, or stop it manually
    logger.warn('DB locked by another process — wait or stop it, then retry');
    // Optionally: await sleep(10000); await doInitLbug(repoId, dbPath);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling initLbug for a repoId while another process (typically `gitnexus analyze` or another `gitnexus serve` instance) holds an exclusive lock on the LadybugDB database file; all 3 retry attempts (at 2s, 4s, 6s) encounter the lock error ('Could not set lock' or matching /lock(b|ed|ing)/i). The loop also breaks early on non-lock errors that aren't retryable.

Common situations: Running `gitnexus serve` while `gitnexus analyze` is rebuilding the same repo's index; two MCP server instances pointing at the same repository; an analyze that crashed and left a stale lock file; a long-running analyze on a large repo that holds the lock for minutes.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/806822f443537509. Report an issue: GitHub.