{"record":{"id":"2c842e4250ff0482","repo":"stablyai/orca","slug":"benchmark-process-group-authority-recovery-failed","errorCode":null,"errorMessage":"Benchmark process group authority recovery failed","messagePattern":"Benchmark process group authority recovery failed","errorType":"exception","errorClass":"AggregateError","httpStatus":null,"severity":"error","filePath":"config/scripts/macos-computer-helper-owner-loss-processes.mjs","lineNumber":256,"sourceCode":"      throw new AggregateError(\n        [error, ...recoveryErrors],\n        'Benchmark process group recovery failed before validation'\n      )\n    }\n    throw error\n  }\n  if (members.length === 0) {\n    const recoveryErrors = compensateStoppedGroup(pgid, groupState, operations)\n    if (recoveryErrors.length > 0) {\n      throw new AggregateError(recoveryErrors, 'Benchmark missing process group recovery failed')\n    }\n    return false\n  }\n  if (members.some((identity) => !identity.command.includes(environmentFragment))) {\n    const ownershipError = new Error('Benchmark process group no longer belongs to this trial')\n    const recoveryErrors = compensateStoppedGroup(pgid, groupState, operations)\n    if (recoveryErrors.length > 0) {\n      throw new AggregateError(\n        [ownershipError, ...recoveryErrors],\n        'Benchmark process group authority recovery failed'\n      )\n    }\n    throw ownershipError\n  }\n  if (groupState.anchorPid) {\n    try {\n      operations.signalProcess(groupState.anchorPid, 'SIGCONT')\n      groupState.anchorPid = null\n    } catch (error) {\n      if (error?.code === 'ESRCH') {\n        groupState.anchorPid = null\n      } else {\n        throw new AggregateError([error], 'Benchmark pending anchor recovery failed')\n      }\n    }\n  }","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/macos-computer-helper-owner-loss-processes.mjs#L238-L274","documentation":"In signalValidatedProcessGroup, the process group has members but some have commands that do not contain the environmentFragment — meaning the group has been hijacked or a PID was recycled to a different process. The ownership error plus any recovery failures from compensateStoppedGroup are wrapped in an AggregateError.","triggerScenarios":"At line 252, members.some(identity => !identity.command.includes(environmentFragment)) is true — a process in the pgid has a command string that doesn't contain the expected environment marker. Then compensateStoppedGroup also fails for non-ESRCH reasons. recoveryErrors.length > 0 at line 255.","commonSituations":"PID recycling: a helper process exited and its PID was reused by an unrelated process that inherited the same pgid; the environmentFragment is too generic and matches unrelated processes; a previous trial's processes were not fully cleaned up and share the pgid namespace.","solutions":["Inspect the process group members' commands with `ps -o pid,pgid,command` to detect PID recycling or foreign processes","Make the environmentFragment more specific (include a unique temp dir path or trial ID from the environment)","Ensure thorough cleanup between trials so no stale processes share the pgid","Inspect AggregateError.errors: errors[0] is the ownership error, errors[1+] are recovery failures"],"exampleFix":"// before: environmentFragment is too generic, matches unrelated processes\nconst fragment = 'orca-computer-use-macos'\n\n// after: include the trial-specific temp dir for uniqueness\nconst fragment = path.join(trialTempDir, 'orca-computer-use-macos')","handlingStrategy":"try-catch","validationCode":"// Pre-check: verify all group members belong to this trial\nconst members = processIdentities(true).filter(id => id.pgid === pgid)\nconst foreign = members.filter(id => !id.command.includes(envFragment))\nif (foreign.length > 0) {\n  console.warn('Foreign processes in group:', foreign.map(f => f.pid))\n  // do not signal — group has been recycled or hijacked\n}","typeGuard":null,"tryCatchPattern":"try {\n  signalValidatedProcessGroup(pgid, envFragment, signal, groupState)\n} catch (error) {\n  if (error instanceof AggregateError && error.message.includes('authority recovery')) {\n    // errors[0] = ownership error, errors[1+] = recovery failures\n    const [ownershipErr] = error.errors\n    console.error('Group authority lost:', ownershipErr.message)\n    // investigate PID recycling — do not force-signal foreign processes\n  }\n  throw error\n}","preventionTips":["Use a unique environmentFragment (include trial temp dir path or UUID) to prevent false matches from PID recycling","Ensure thorough inter-trial cleanup so no stale processes share the pgid namespace","Never force-signal a process group containing foreign processes — investigate PID recycling first"],"tags":["process-group","recovery","pid-recycling","aggregate-error"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}