abhigyanpatwari/GitNexus · error · Error

Unable to determine process start time for file lock owner p

Error message

Unable to determine process start time for file lock owner pid ${owner.pid}.

What it means

acquireFileLock builds a FileLockOwner record that must include the owning process's start time, which is used later to detect stale locks (a PID reuse guard). It reads the start time from options.processStartTime or falls back to readProcessStartTime(pid); if both yield nothing, it throws because a lock without a start time cannot be safely reclaimed by other processes.

Source

Thrown at gitnexus/src/storage/file-lock.ts:53

/** Acquire a recoverable cross-process mutex using an atomically published owner file. */
export async function acquireFileLock(
  lockPath: string,
  options: FileLockOptions = {},
): Promise<() => Promise<void>> {
  const resolvedPath = path.resolve(lockPath);
  const retries = options.retries ?? 0;
  const retryDelayMs = options.retryDelayMs ?? 50;
  const pid = options.pid ?? process.pid;
  const owner: FileLockOwner = {
    pid,
    ownerId: crypto.randomUUID(),
    processStartTime:
      options.processStartTime ?? (options.readProcessStartTime ?? readProcessStartTime)(pid) ?? '',
    hostname: options.hostname ?? HOSTNAME,
  };
  if (!owner.processStartTime) {
    throw new Error(`Unable to determine process start time for file lock owner pid ${owner.pid}.`);
  }

  await fs.mkdir(path.dirname(resolvedPath), { recursive: true });
  const pendingPath = `${resolvedPath}.pending-${owner.ownerId}`;
  await fs.writeFile(pendingPath, `${JSON.stringify(owner)}\n`, { encoding: 'utf-8', flag: 'wx' });

  try {
    for (let attempt = 0; ; attempt += 1) {
      try {
        await fs.link(pendingPath, resolvedPath);
        break;
      } catch (error) {
        if (!(await isLockConflict(error, resolvedPath))) throw error;
        if (
          await reclaimStaleLock(
            resolvedPath,
            owner,
            options.isProcessAlive ?? isProcessAlive,

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Pass options.processStartTime explicitly (e.g. read it yourself via `ps -p <pid> -o lstart=` or /proc/<pid>/stat field 22) when the automatic lookup is unavailable.
  2. Ensure the pid passed via options.pid is a live process on the current machine.
  3. Check that utils/process-identity readProcessStartTime supports the platform; supply a custom readProcessStartTime in options for unsupported platforms.
  4. If this occurs inside reclaimStaleLock, confirm the caller supplied a valid guardOwner.processStartTime.

Example fix

// before
await acquireFileLock(lockPath, { pid: workerPid });
// after
await acquireFileLock(lockPath, { pid: workerPid, processStartTime: getStartTime(workerPid) });
Defensive patterns

Strategy: try-catch

Validate before calling

const startTime = options.processStartTime ?? readProcessStartTime(pid);
if (!startTime) throw new Error(`Cannot acquire lock: no start time for pid ${pid}`);

Type guard

function hasProcessStartTime(o: FileLockOptions & { processStartTime?: string }): o is FileLockOptions & { processStartTime: string } {
  return typeof o.processStartTime === 'string' && o.processStartTime.length > 0;
}

Try / catch

try {
  const release = await acquireFileLock(lockPath, options);
  // ...
} catch (err) {
  if (err instanceof Error && err.message.includes('Unable to determine process start time')) {
    // fall back to explicit processStartTime or skip locking
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling acquireFileLock (directly or via acquireWatchLock, resetAutoSyncState, run, reclaimStaleLock, release, nextRelease) when options.processStartTime is undefined and readProcessStartTime(pid) returns undefined — e.g. the pid no longer exists, the OS does not expose /proc-style start-time info (unsupported platform), or a custom readProcessStartTime returns undefined.

Common situations: Running on a platform/container where the start-time lookup fails; passing an options.pid that is not a live process; a mocked or overridden readProcessStartTime (test harness) returning undefined; missing explicit processStartTime in constrained environments.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08). Data as JSON: /api/errors/c7e7b77ddcfd92fa. Report an issue: GitHub.