stablyai/orca · error · Error
Benchmark process group anchor changed before signaling
Error message
Benchmark process group anchor changed before signaling
What it means
Thrown inside signalValidatedProcessGroup right after SIGSTOP'ing the anchor (members[0]). The code re-fetches all process identities and looks up the anchor pid; if sameIdentity (pid + pgid + command) no longer matches the pre-stop snapshot, the anchor was replaced in the stop window and signaling the group by -pgid would hit the wrong process. This is a deliberate TOCTOU guard, not a recoverable fault.
Source
Thrown at config/scripts/macos-computer-helper-owner-loss-processes.mjs:283
operations.signalProcess(groupState.anchorPid, 'SIGCONT')
groupState.anchorPid = null
} catch (error) {
if (error?.code === 'ESRCH') {
groupState.anchorPid = null
} else {
throw new AggregateError([error], 'Benchmark pending anchor recovery failed')
}
}
}
const anchor = members[0]
try {
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')
}View on GitHub (pinned to 1136503c6a)
Solutions
- Treat as a trial-invalid signal: abort the trial, run compensateStoppedGroup, and re-spawn the helper from scratch
- Reduce the window between snapshot and re-check by capturing anchor identity and stopping in the same critical section
- Confirm the helper was healthy before signaling (waitForIdentityExit on a no-op signal 0) to avoid stopping an already-dying process
- If recurring, raise the helper's SIGCHLD handling so it does not self-terminate on SIGSTOP
Defensive patterns
Strategy: try-catch
Try / catch
try {
signalValidatedProcessGroup(pgid, frag, sig, state)
} catch (error) {
if (/anchor changed before signaling/.test(error.message)) {
respawnHelperAndRetry()
} else throw error
} Prevention
- Treat anchor-identity drift as a signal to re-spawn, not a transient retry
- Keep the window between snapshot and SIGSTOP minimal
- Log members[0] identity at capture time to compare on failure
When it happens
Trigger: Between operations.signalProcess(anchor.pid, 'SIGSTOP') and the processIdentities(true).find(...) re-check, the anchor exited and the OS recycled its PID for an unrelated process, so the returned identity has a different pgid or command.
Common situations: Long-running benchmark harnesses on systems under heavy process churn, containers where PID recycling is aggressive, or when the anchor helper crashed immediately on SIGSTOP and a sibling process grabbed the PID. Also surfaces if processIdentities is stubbed to return inconsistent data.
Related errors
- Recorded benchmark helper PID changed before signaling
- Benchmark process group changed before signaling
- Recorded benchmark helper PID now belongs to another process
- Benchmark pending anchor recovery failed
- Benchmark process group signal recovery failed
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/f0301809f4bc7965.
Report an issue: GitHub.