stablyai/orca · error · AggregateError

Electron trial and cleanup failed

Error message

Electron trial and cleanup failed

What it means

throwBenchmarkTrialFailures is called when both the Electron trial itself errored (trialError) and the subsequent cleanup also errored (cleanupError). It wraps both in an AggregateError so neither error is lost. This preserves the root-cause trial error alongside the cleanup failure for diagnosis.

Source

Thrown at config/scripts/macos-computer-helper-owner-loss-processes.mjs:178

  const errors = []
  for (const stage of stages) {
    try {
      stage()
    } catch (error) {
      errors.push(error)
    }
  }
  if (errors.length === 1) {
    throw errors[0]
  }
  if (errors.length > 1) {
    throw new AggregateError(errors, 'Benchmark trial cleanup failed')
  }
}

export function throwBenchmarkTrialFailures(trialError, cleanupError) {
  if (trialError && cleanupError) {
    throw new AggregateError([trialError, cleanupError], 'Electron trial and cleanup failed')
  }
  if (trialError) {
    throw trialError
  }
  if (cleanupError) {
    throw cleanupError
  }
}

export function parseBenchmarkTrialResult(serializedResult) {
  return JSON.parse(serializedResult)
}

export function benchmarkTrialNeedsCleanup(spawnResult, parsedResultAvailable) {
  return spawnResult?.status !== 0 || !parsedResultAvailable
}

const processGroupSignalOperations = {

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Inspect AggregateError.errors[0] (trial error) and errors[1] (cleanup error) separately — fix the trial error first
  2. Read the trial's stdout.log and stderr.log in the launcher temp dir for the root cause of the trial failure
  3. Manually clean up leftover processes so subsequent runs don't compound cleanup errors
  4. Fixing the trial error often resolves the cleanup error (fewer leftover processes)

Example fix

// before: trial and cleanup errors are hard to separate
try {
  const result = runTrial(executable, 'reaped')
} catch (e) {
  console.error(e.message) // 'Electron trial and cleanup failed'
}

// after: distinguish trial vs cleanup failures
try {
  const result = runTrial(executable, 'reaped')
} catch (e) {
  if (e instanceof AggregateError) {
    console.error('TRIAL:', e.errors[0]?.message)
    console.error('CLEANUP:', e.errors[1]?.message)
  }
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const result = runTrial(executable, 'reaped')
} catch (error) {
  if (error instanceof AggregateError && error.message.includes('trial and cleanup')) {
    // Separate trial error from cleanup error for diagnosis
    const [trialErr, cleanupErr] = error.errors
    console.error('TRIAL:', trialErr.message)
    console.error('CLEANUP:', cleanupErr.message)
    // Fix the trial error first — it usually resolves cleanup too
  }
  throw error
}

Prevention

When it happens

Trigger: In runTrial (line 522): the Electron subprocess crashed, timed out, or produced no result (trialError set), AND the cleanup in the finally block also failed (cleanupError set from cleanupOwnerLossTrial). Both are non-null, so throwBenchmarkTrialFailures wraps them.

Common situations: Trial times out (Electron hangs) and leftover processes can't be killed; trial crashes and the result file doesn't exist, and temp dir cleanup also fails; the helper spawned but the sidecar died, leaving processes that cleanup can't reach.

Related errors


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