{"record":{"id":"c7e7b77ddcfd92fa","repo":"abhigyanpatwari/GitNexus","slug":"unable-to-determine-process-start-time-for-file-lo","errorCode":null,"errorMessage":"Unable to determine process start time for file lock owner pid ${owner.pid}.","messagePattern":"Unable to determine process start time for file lock owner pid (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/storage/file-lock.ts","lineNumber":53,"sourceCode":"\n/** Acquire a recoverable cross-process mutex using an atomically published owner file. */\nexport async function acquireFileLock(\n  lockPath: string,\n  options: FileLockOptions = {},\n): Promise<() => Promise<void>> {\n  const resolvedPath = path.resolve(lockPath);\n  const retries = options.retries ?? 0;\n  const retryDelayMs = options.retryDelayMs ?? 50;\n  const pid = options.pid ?? process.pid;\n  const owner: FileLockOwner = {\n    pid,\n    ownerId: crypto.randomUUID(),\n    processStartTime:\n      options.processStartTime ?? (options.readProcessStartTime ?? readProcessStartTime)(pid) ?? '',\n    hostname: options.hostname ?? HOSTNAME,\n  };\n  if (!owner.processStartTime) {\n    throw new Error(`Unable to determine process start time for file lock owner pid ${owner.pid}.`);\n  }\n\n  await fs.mkdir(path.dirname(resolvedPath), { recursive: true });\n  const pendingPath = `${resolvedPath}.pending-${owner.ownerId}`;\n  await fs.writeFile(pendingPath, `${JSON.stringify(owner)}\\n`, { encoding: 'utf-8', flag: 'wx' });\n\n  try {\n    for (let attempt = 0; ; attempt += 1) {\n      try {\n        await fs.link(pendingPath, resolvedPath);\n        break;\n      } catch (error) {\n        if (!(await isLockConflict(error, resolvedPath))) throw error;\n        if (\n          await reclaimStaleLock(\n            resolvedPath,\n            owner,\n            options.isProcessAlive ?? isProcessAlive,","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/storage/file-lock.ts#L35-L71","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Ensure the pid passed via options.pid is a live process on the current machine.","Check that utils/process-identity readProcessStartTime supports the platform; supply a custom readProcessStartTime in options for unsupported platforms.","If this occurs inside reclaimStaleLock, confirm the caller supplied a valid guardOwner.processStartTime."],"exampleFix":"// before\nawait acquireFileLock(lockPath, { pid: workerPid });\n// after\nawait acquireFileLock(lockPath, { pid: workerPid, processStartTime: getStartTime(workerPid) });","handlingStrategy":"try-catch","validationCode":"const startTime = options.processStartTime ?? readProcessStartTime(pid);\nif (!startTime) throw new Error(`Cannot acquire lock: no start time for pid ${pid}`);","typeGuard":"function hasProcessStartTime(o: FileLockOptions & { processStartTime?: string }): o is FileLockOptions & { processStartTime: string } {\n  return typeof o.processStartTime === 'string' && o.processStartTime.length > 0;\n}","tryCatchPattern":"try {\n  const release = await acquireFileLock(lockPath, options);\n  // ...\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Unable to determine process start time')) {\n    // fall back to explicit processStartTime or skip locking\n  }\n  throw err;\n}","preventionTips":["Always pass an explicit processStartTime when acquiring locks with a custom pid.","Test lock acquisition on every target platform (not all expose process start times).","Never pass a dead or foreign pid as options.pid.","Wrap custom readProcessStartTime implementations so they never return undefined silently — log it."],"tags":["file-lock","process-start-time","stale-lock-detection"],"backgroundTag":"missing-required-argument","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-09-08T00:40:44.970Z","contentChangedAt":"2026-09-08T00:40:44.970Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}