abhigyanpatwari/GitNexus · warning
GitNexus: unable to inspect init lock (${code ?? 'UNKNOWN'})
Error message
GitNexus: unable to inspect init lock (${code ?? 'UNKNOWN'}): ${summarizeError(err)} What it means
Thrown during tryBreakStaleLock while deciding whether an existing init lock file (O_CREAT|O_EXCL) can be reclaimed. The function read the lock, found the PID gone or the lock older than INIT_LOCK_STALE_MS, but then hit a non-ENOENT filesystem error (EACCES/EPERM, EIO, unparsable content path). It returns false, meaning 'do not break it; let the caller retry the acquire loop' rather than deleting a lock it cannot inspect.
Source
Thrown at gitnexus/src/core/lbug/lbug-adapter.ts:378
// (e.g. the process is hung). Check the timestamp.
if (typeof parsed.ts === 'number' && Date.now() - parsed.ts < INIT_LOCK_STALE_MS) {
return false;
}
}
// PID is gone or lock exceeded INIT_LOCK_STALE_MS — reclaim it.
await fs.unlink(lockPath);
logger.warn(
`GitNexus: removed stale init lock (pid=${parsed.pid ?? '?'}, age=${typeof parsed.ts === 'number' ? `${Date.now() - parsed.ts}ms` : '?'})`,
);
return true;
} catch (err) {
// Lock file disappeared between our read and unlink, or is unreadable.
// Either way, let the caller retry the acquire.
if (isMissingFileError(err)) return true;
// Permission error or corrupt content — log and let caller retry.
const code = extractErrnoCode(err);
logger.warn(
`GitNexus: unable to inspect init lock (${code ?? 'UNKNOWN'}): ${summarizeError(err)}`,
);
return false;
}
};
/**
* Acquire a cross-process init lock for `dbPath`.
* Uses `O_CREAT | O_EXCL` for atomic create-or-fail semantics.
*
* Returns a release function that removes the lock file. The release
* function is idempotent and safe to call even if the lock was already
* cleaned up externally.
*
* Throws if the lock cannot be acquired after `INIT_LOCK_MAX_ATTEMPTS`.
*/
export const acquireInitLock = async (dbPath: string): Promise<() => Promise<void>> => {
const lockPath = initLockPath(dbPath);View on GitHub (pinned to aac7515d2a)
Solutions
- Inspect the lock file next to the DB path: `ls -l <dbPath>*lock*` and check owner/permissions; chown/chmod it so the current user can read and unlink it.
- If no other gitnexus process is running, delete the stale lock file manually and retry the operation.
- Ensure only one user/context (same UID) runs `analyze`/`serve` against the same .gitnexus database directory.
- Retry the command — the acquire loop tolerates transient races and the warn is non-fatal.
Example fix
# before: analyze fails to acquire, warns 'unable to inspect init lock (EACCES)' ls -la .gitnexus/*.lock # shows root-owned lock from an earlier sudo run # after sudo rm .gitnexus/*.lock && gitnexus analyze
Defensive patterns
Strategy: retry
Validate before calling
// Before initLbug: assert the lock file is readable/unlinkable by this user
import { access, constants } from 'node:fs/promises';
try {
await access(lockPath, constants.R_OK | constants.W_OK);
} catch {
// unreadable lock: fix ownership now instead of looping the acquire retry
throw new Error(`init lock ${lockPath} not accessible by uid=${process.getuid?.()}`);
} Try / catch
// tryBreakStaleLock returns boolean: false means 'could not inspect, retry acquire'
if (!(await tryBreakStaleLock(lockPath))) {
await sleep(backoffMs);
continue; // retry the O_EXCL acquire; give up after N attempts with a clear error
} Prevention
- Run all gitnexus commands against one repo as the same OS user.
- Keep the .gitnexus directory off permission-quirky network mounts.
- Clean up lock files when tearing down containers that share volumes.
When it happens
Trigger: initLbug(dbPath) is called while a lock file exists at `${dbPath}.init.lock`-style path; tryBreakStaleLock's fs operations fail with EACCES (lock created by another user/root), EIO, or the unlink races in a way that is not ENOENT. The acquire loop then retries, so the caller may loop until the situation changes.
Common situations: Indexing the same repo as root and then as a normal user (or vice versa); lock files on NFS/network mounts with permission quirks; containers sharing a volume with differing UIDs; security software briefly locking files mid-inspect.
Related errors
- GitNexus: unable to acquire init lock after ${INIT_LOCK_MAX_
- GitNexus: failed to release init lock (${code ?? 'UNKNOWN'})
- ${source}: branch name must not contain whitespace.
- GitNexus could not move the LadybugDB WAL sidecar at ${dbPat
- LadybugDB checkpoint sidecar is missing for ${dbPath}. Rebui
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/60fb2deb1a89c075.
Report an issue: GitHub.