stablyai/orca · error · Error
Benchmark process group changed before signaling
Error message
Benchmark process group changed before signaling
What it means
Thrown after SIGSTOP'ing the whole process group (-pgid). The code re-enumerates members of pgid and requires (a) at least one member survives and (b) every surviving member's command still contains environmentFragment. Failure means the group's composition drifted during the stop — members exited or were replaced by unrelated processes sharing the pgid.
Source
Thrown at config/scripts/macos-computer-helper-owner-loss-processes.mjs:295
operations.signalProcess(anchor.pid, 'SIGSTOP')
groupState.anchorPid = anchor.pid
const stoppedAnchor = operations
.processIdentities(true)
.find((identity) => identity.pid === anchor.pid)
if (!sameIdentity(stoppedAnchor, anchor)) {
throw new Error('Benchmark process group anchor changed before signaling')
}
operations.signalProcess(-pgid, 'SIGSTOP')
groupState.stopped = true
groupState.anchorPid = null
const stoppedMembers = operations
.processIdentities(true)
.filter((identity) => identity.pgid === pgid)
if (
stoppedMembers.length === 0 ||
stoppedMembers.some((identity) => !identity.command.includes(environmentFragment))
) {
throw new Error('Benchmark process group changed before signaling')
}
if (signal !== 'SIGSTOP') {
operations.signalProcess(-pgid, signal)
if (signal !== 'SIGKILL') {
operations.signalProcess(-pgid, 'SIGCONT')
}
groupState.stopped = false
groupState.anchorPid = null
}
return true
} catch (error) {
const recoveryErrors = compensateStoppedGroup(pgid, groupState, operations)
if (recoveryErrors.length > 0) {
throw new AggregateError(
[error, ...recoveryErrors],
'Benchmark process group signal recovery failed'
)
}View on GitHub (pinned to 1136503c6a)
Solutions
- Re-run the trial after re-spawning the helper — group drift is not recoverable mid-signal
- Widen environmentFragment to a stable argv token that survives helper refactors (an env var like ORCA_BENCH_ROLE rather than a path)
- Spawn the helper with setsid or a dedicated posix_spawnattr pgid to prevent foreign processes joining the group
- Log stoppedMembers at the catch site to see whether members vanished or commands drifted
Defensive patterns
Strategy: try-catch
Try / catch
try {
signalValidatedProcessGroup(pgid, frag, sig, state)
} catch (error) {
if (/process group changed before signaling/.test(error.message)) {
respawnHelperAndRetry()
} else throw error
} Prevention
- Use a stable environmentFragment (an env var token) rather than a brittle path substring
- Spawn helpers with setsid or a dedicated pgid so foreign processes cannot join the group
- Log stoppedMembers in the catch to distinguish vanished members from command drift
When it happens
Trigger: operations.signalProcess(-pgid, 'SIGSTOP') succeeds, but the subsequent processIdentities(true).filter(pgid === ...) returns either an empty list or members whose command no longer contains environmentFragment.
Common situations: A helper child exits between the anchor stop and the group stop; a setpgid race places an unrelated process into the same pgid; or environmentFragment was chosen too narrowly and no longer matches the helper's actual command line (e.g. after an argv refactor).
Related errors
- Benchmark process group anchor changed before signaling
- Recorded benchmark helper PID changed before signaling
- Benchmark pending anchor recovery failed
- Benchmark process group signal recovery failed
- Benchmark helper signal recovery failed
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/a93f7588160d2d4b.
Report an issue: GitHub.