stablyai/orca · error · Error

Could not inspect process ${pid}: ${raw}

Error message

Could not inspect process ${pid}: ${raw}

What it means

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.

Source

Thrown at config/scripts/macos-computer-helper-owner-loss-metrics.mjs:42

  const parts = clock.split(':').map(Number)
  if (!Number.isFinite(days) || parts.some((part) => !Number.isFinite(part))) {
    throw new Error(`Invalid process CPU time: ${value}`)
  }
  const seconds = parts.pop() ?? 0
  const minutes = parts.pop() ?? 0
  const hours = parts.pop() ?? 0
  return days * 86_400 + hours * 3_600 + minutes * 60 + seconds
}

export function processSnapshot(pid) {
  const raw = execFileSync(
    'ps',
    ['-o', 'rss=', '-o', 'time=', '-o', 'command=', '-p', String(pid)],
    { encoding: 'utf8' }
  ).trim()
  const match = raw.match(/^(\d+)\s+(\S+)\s+(.+)$/)
  if (!match) {
    throw new Error(`Could not inspect process ${pid}: ${raw}`)
  }
  return {
    rssBytes: Number(match[1]) * 1024,
    cpuTimeSeconds: parseCpuTimeSeconds(match[2]),
    command: match[3]
  }
}

export async function sampleProcess(pid) {
  const samples = []
  for (let index = 0; index < SAMPLE_COUNT; index += 1) {
    samples.push(processSnapshot(pid))
    await sleep(SAMPLE_INTERVAL_MS)
  }
  return {
    rssBytes: median(samples.map((sample) => sample.rssBytes)),
    cpuTimeSeconds: samples.at(-1).cpuTimeSeconds,
    command: samples.at(-1).command

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Re-check process liveness immediately before calling processSnapshot to minimize the race window
  2. Handle empty ps output as 'process gone' rather than throwing — return a zero/null snapshot
  3. Pin LC_ALL=C for ps to avoid locale-dependent whitespace or field separators

Example fix

// before: race between liveness check and snapshot
if (isProcessAlive(pid)) {
  return processSnapshot(pid) // process may die here
}

// after: treat snapshot failure as 'gone'
try {
  return processSnapshot(pid)
} catch {
  return { rssBytes: 0, cpuTimeSeconds: 0, command: '' }
}
Defensive patterns

Strategy: validation

Validate before calling

// Re-check liveness immediately before snapshot to minimize the race window
function safeSnapshot(pid) {
  if (!isProcessAlive(pid)) {
    return { rssBytes: 0, cpuTimeSeconds: 0, command: '' }
  }
  return processSnapshot(pid)
}

Try / catch

try {
  return processSnapshot(pid)
} catch (error) {
  if (error.message.includes('Could not inspect process')) {
    // process likely exited between liveness check and ps call
    return { rssBytes: 0, cpuTimeSeconds: 0, command: '' }
  }
  throw error
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/8822ac38dc9f3747. Report an issue: GitHub.