stablyai/orca · error · Error

Could not read watchdog child RSS for PID ${pid}

Error message

Could not read watchdog child RSS for PID ${pid}

What it means

Thrown by childRssBytes() when `ps -o rss= -p <pid>` returns output that is not a finite positive number. RSS (resident set size, in KiB) is parsed to bytes for the watchdog child process memory measurement. A non-positive or NaN result means the PID is gone or ps output is unparseable.

Source

Thrown at config/scripts/hang-watchdog-process-metrics.mjs:30

  const physicalFootprintSamples = []
  for (let index = 0; index < options.sampleCount; index += 1) {
    rssSamples.push(readRss())
    physicalFootprintSamples.push(readPhysicalFootprint())
    await options.sleep(options.sampleIntervalMs)
  }
  return {
    rssBytes: median(rssSamples),
    physicalFootprintBytes: median(physicalFootprintSamples)
  }
}

export function childRssBytes(pid) {
  const raw = execFileSync('ps', ['-o', 'rss=', '-p', String(pid)], {
    encoding: 'utf8'
  }).trim()
  const rssKiB = Number(raw)
  if (!Number.isFinite(rssKiB) || rssKiB <= 0) {
    throw new Error(`Could not read watchdog child RSS for PID ${pid}`)
  }
  return rssKiB * 1024
}

export function parsePhysicalFootprintBytes(output, processCount) {
  const match =
    processCount > 1
      ? output.match(/^Summary Footprint:\s+(\d+) B$/m)
      : output.match(/^[^\s].*\sFootprint:\s+(\d+) B/m)
  const bytes = Number(match?.[1])
  return Number.isFinite(bytes) && bytes > 0 ? bytes : null
}

export function physicalFootprintBytes(pids) {
  const pidArgs = pids.flatMap((pid) => ['--pid', String(pid)])
  const output = execFileSync(
    '/usr/bin/footprint',
    [...pidArgs, '--format', 'bytes', '--noCategories'],

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Verify the child PID is still alive before sampling: `process.kill(pid, 0)`.
  2. Ensure the child is not being killed externally during the measurement window.
  3. Debug by running `ps -o rss= -p <pid>` manually during a trial.

Example fix

// before
const rss = childRssBytes(child.pids[1])  // throws if child exited
// after
if (child.exitCode !== null) throw new Error('child exited before RSS sample')
const rss = childRssBytes(child.pids[1])
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the child is alive before sampling RSS
function isAlive(pid: number): boolean {
  try { process.kill(pid, 0); return true } catch { return false }
}
if (!isAlive(pid)) throw new Error(`pid ${pid} exited before RSS sample`)

Type guard

const isProcessAlive = (pid: number): boolean => { try { process.kill(pid, 0); return true } catch { return false } }

Prevention

When it happens

Trigger: The child PID exited before the read (race between measurement and shutdown), the PID was recycled, or ps produced empty/malformed output (e.g. locale/formatting differences).

Common situations: The watchdog child crashed or was killed mid-sampling, a slow shutdown timing overlap, or running on a macOS version where ps column formatting differs.

Related errors


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