{"record":{"id":"2f6ac4a8a081f19b","repo":"stablyai/orca","slug":"could-not-parse-process-identity-for-pid","errorCode":null,"errorMessage":"Could not parse process identity for ${pid}","messagePattern":"Could not parse process identity for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/macos-computer-helper-owner-loss-processes.mjs","lineNumber":25,"sourceCode":"\nconst processIdentityOperations = {\n  executePs: execFileSync,\n  signalProcess: process.kill.bind(process)\n}\n\nexport function processIdentity(pid, operations = processIdentityOperations) {\n  if (!Number.isInteger(pid) || pid <= 0) {\n    return null\n  }\n  try {\n    const output = operations\n      .executePs('ps', ['-p', String(pid), '-o', 'pid=,pgid=,command='], {\n        encoding: 'utf8'\n      })\n      .trim()\n    const match = output.match(/^(\\d+)\\s+(\\d+)\\s+(.+)$/)\n    if (!match) {\n      throw new Error(`Could not parse process identity for ${pid}`)\n    }\n    return { pid: Number(match[1]), pgid: Number(match[2]), command: match[3] }\n  } catch (error) {\n    try {\n      operations.signalProcess(pid, 0)\n    } catch (lookupError) {\n      if (lookupError?.code === 'ESRCH') {\n        return null\n      }\n    }\n    throw error\n  }\n}\n\nfunction matchingDetachedProcesses(identities, expectedCommandFragments) {\n  return identities.filter(\n    (identity) =>\n      identity.pgid === identity.pid &&","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/macos-computer-helper-owner-loss-processes.mjs#L7-L43","documentation":"processIdentity(pid) runs `ps -p <pid> -o pid=,pgid=,command=` and expects output matching ^(\\d+)\\s+(\\d+)\\s+(.+)$ (pid, pgid, command). If the output does not match, it throws. However, the outer catch (line 28) attempts signalProcess(pid, 0) — if that returns ESRCH (no such process), it returns null. So this error only propagates if the process IS alive but ps output is unparseable.","triggerScenarios":"Process is alive (signal 0 succeeds) but `ps -p <pid> -o pid=,pgid=,command=` output does not match the three-field regex. Extremely rare: would require a non-standard ps, locale corruption, or kernel-thread PID with blank fields.","commonSituations":"Non-C locale altering ps field formatting; macOS ps version producing unexpected whitespace for special processes; the PID points to a kernel task with no command string.","solutions":["Pin LC_ALL=C for ps invocations","If the process is alive but ps fails, fall back to /proc-style inspection or proc_pidinfo via native bindings","Log the raw ps output to diagnose the format mismatch"],"exampleFix":"// before: ps may produce locale-dependent output for live process\nconst output = operations.executePs('ps', ['-p', String(pid), '-o', 'pid=,pgid=,command='], { encoding: 'utf8' })\n\n// after: pin locale\nconst output = operations.executePs('ps', ['-p', String(pid), '-o', 'pid=,pgid=,command='], {\n  encoding: 'utf8',\n  env: { ...process.env, LC_ALL: 'C' }\n})","handlingStrategy":"try-catch","validationCode":"// Pin locale and check liveness before identity lookup\nprocess.env.LC_ALL = 'C'\nfunction safeProcessIdentity(pid) {\n  if (!Number.isInteger(pid) || pid <= 0) return null\n  if (!isProcessAlive(pid)) return null\n  return processIdentity(pid)\n}","typeGuard":null,"tryCatchPattern":"// The function already has a built-in catch that returns null on ESRCH.\n// Wrap the caller to handle the rare live-but-unparseable case:\ntry {\n  return processIdentity(pid)\n} catch (error) {\n  if (error.message.includes('Could not parse process identity')) {\n    console.warn('Live process has unparseable ps output:', pid)\n    return null\n  }\n  throw error\n}","preventionTips":["Pin LC_ALL=C for all ps invocations to ensure consistent field formatting","Check process liveness before calling processIdentity to avoid races","The built-in ESRCH catch already handles dead processes — this error only fires for live processes with malformed ps output"],"tags":["process-lifecycle","parsing","ps"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}