{"record":{"id":"8822ac38dc9f3747","repo":"stablyai/orca","slug":"could-not-inspect-process-pid-raw","errorCode":null,"errorMessage":"Could not inspect process ${pid}: ${raw}","messagePattern":"Could not inspect process (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/macos-computer-helper-owner-loss-metrics.mjs","lineNumber":42,"sourceCode":"  const parts = clock.split(':').map(Number)\n  if (!Number.isFinite(days) || parts.some((part) => !Number.isFinite(part))) {\n    throw new Error(`Invalid process CPU time: ${value}`)\n  }\n  const seconds = parts.pop() ?? 0\n  const minutes = parts.pop() ?? 0\n  const hours = parts.pop() ?? 0\n  return days * 86_400 + hours * 3_600 + minutes * 60 + seconds\n}\n\nexport function processSnapshot(pid) {\n  const raw = execFileSync(\n    'ps',\n    ['-o', 'rss=', '-o', 'time=', '-o', 'command=', '-p', String(pid)],\n    { encoding: 'utf8' }\n  ).trim()\n  const match = raw.match(/^(\\d+)\\s+(\\S+)\\s+(.+)$/)\n  if (!match) {\n    throw new Error(`Could not inspect process ${pid}: ${raw}`)\n  }\n  return {\n    rssBytes: Number(match[1]) * 1024,\n    cpuTimeSeconds: parseCpuTimeSeconds(match[2]),\n    command: match[3]\n  }\n}\n\nexport async function sampleProcess(pid) {\n  const samples = []\n  for (let index = 0; index < SAMPLE_COUNT; index += 1) {\n    samples.push(processSnapshot(pid))\n    await sleep(SAMPLE_INTERVAL_MS)\n  }\n  return {\n    rssBytes: median(samples.map((sample) => sample.rssBytes)),\n    cpuTimeSeconds: samples.at(-1).cpuTimeSeconds,\n    command: samples.at(-1).command","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/macos-computer-helper-owner-loss-metrics.mjs#L24-L60","documentation":"processSnapshot(pid) runs `ps -o rss= -o time= -o command= -p <pid>` and expects output matching ^(\\d+)\\s+(\\S+)\\s+(.+)$ (RSS, time, command). If the output is empty, multi-line, or does not match this three-field pattern, the regex match fails and the error fires.","triggerScenarios":"The process exited between the liveness check and the ps call (ps returns empty for a dead PID); ps returns a zombie with truncated fields; the command column is empty or whitespace-only; ps output has unexpected leading/trailing whitespace that breaks the anchored regex.","commonSituations":"Race condition: process dies between isProcessAlive check and processSnapshot call; the PID was recycled to a kernel thread with no command; ps format variation across macOS versions.","solutions":["Re-check process liveness immediately before calling processSnapshot to minimize the race window","Handle empty ps output as 'process gone' rather than throwing — return a zero/null snapshot","Pin LC_ALL=C for ps to avoid locale-dependent whitespace or field separators"],"exampleFix":"// before: race between liveness check and snapshot\nif (isProcessAlive(pid)) {\n  return processSnapshot(pid) // process may die here\n}\n\n// after: treat snapshot failure as 'gone'\ntry {\n  return processSnapshot(pid)\n} catch {\n  return { rssBytes: 0, cpuTimeSeconds: 0, command: '' }\n}","handlingStrategy":"validation","validationCode":"// Re-check liveness immediately before snapshot to minimize the race window\nfunction safeSnapshot(pid) {\n  if (!isProcessAlive(pid)) {\n    return { rssBytes: 0, cpuTimeSeconds: 0, command: '' }\n  }\n  return processSnapshot(pid)\n}","typeGuard":null,"tryCatchPattern":"try {\n  return processSnapshot(pid)\n} catch (error) {\n  if (error.message.includes('Could not inspect process')) {\n    // process likely exited between liveness check and ps call\n    return { rssBytes: 0, cpuTimeSeconds: 0, command: '' }\n  }\n  throw error\n}","preventionTips":["Check process liveness immediately before calling processSnapshot","Pin LC_ALL=C for ps to avoid locale-dependent field formatting","Treat snapshot failures as 'process gone' in benchmark hot paths rather than fatal errors"],"tags":["process-metrics","parsing","ps","race-condition"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}