stablyai/orca · error · Error
Watcher supervisor did not replace the faulted child
Error message
Watcher supervisor did not replace the faulted child
What it means
After sending SIGSEGV to firstChildPid and awaiting the interrupted/replacement event, the harness reads supervisor.child?.pid again. It expects a NEW pid (different from firstChildPid) — proving the supervisor auto-respawned the crashed watcher. If the pid is missing or unchanged, the supervisor's self-healing contract is broken and the test fails.
Source
Thrown at config/scripts/runtime-file-watcher-fault-harness.mjs:139
(listener) => {
eventListener = listener
},
(event) => event.path === join(rootPath, 'before.txt'),
'pre-crash watch event'
)
await writeFile(join(rootPath, 'before.txt'), 'before')
await Promise.race([beforeEvent, watcherError])
const firstChildPid = supervisor.child?.pid
if (!firstChildPid) {
throw new Error('Watcher supervisor did not expose a live child')
}
process.kill(firstChildPid, 'SIGSEGV')
await Promise.race([interrupted, watcherError])
const replacementChildPid = supervisor.child?.pid
if (!replacementChildPid || replacementChildPid === firstChildPid) {
throw new Error('Watcher supervisor did not replace the faulted child')
}
const afterEvent = nextMatchingEvent(
(listener) => {
eventListener = listener
},
(event) => event.path === join(rootPath, 'after.txt'),
'post-crash watch event'
)
await writeFile(join(rootPath, 'after.txt'), 'after')
await Promise.race([afterEvent, watcherError])
console.log(
JSON.stringify({
hostPid: process.pid,
killedWatcherPid: firstChildPid,
replacementWatcherPid: replacementChildPid,
hostSurvived: true,
automaticResubscribe: true,View on GitHub (pinned to 1136503c6a)
Solutions
- Confirm the SIGSEGV was sent to the child pid, not the supervisor pid (the harness uses firstChildPid).
- Await the supervisor's respawn promise/event (the harness races interrupted vs watcherError — extend the race to include the respawn signal).
- Re-enable/fix the supervisor's auto-respawn logic; this assertion exists precisely to catch its removal.
- If the supervisor intentionally does not respawn, this test is N/A — skip it on that code path.
Example fix
// before process.kill(firstChildPid, 'SIGSEGV') await Promise.race([interrupted, watcherError]) const replacementChildPid = supervisor.child?.pid // after process.kill(firstChildPid, 'SIGSEGV') await supervisor.waitForRespawn() // explicit respawn signal const replacementChildPid = supervisor.child?.pid
Defensive patterns
Strategy: validation
Validate before calling
const replacement = supervisor.child?.pid
if (typeof replacement !== 'number' || replacement === firstChildPid) {
console.error('Supervisor did not respawn the faulted child'); process.exit(1)
} Type guard
function isRespawned(next: number | undefined, prev: number): next is number {
return typeof next === 'number' && next !== prev
} Try / catch
if (!isRespawned(supervisor.child?.pid, firstChildPid)) {
throw new Error('Watcher supervisor did not replace the faulted child')
} Prevention
- Await the supervisor's explicit respawn event before reading the new pid.
- Confirm SIGSEGV targeted the child pid, not the supervisor pid.
- Keep this assertion in place — it guards the auto-respawn contract.
When it happens
Trigger: The supervisor did not respawn the child after SIGSEGV (no recovery logic), respawned but reused the same pid (impossible normally), or the replacement race window closed before the read.
Common situations: A regression in WatcherProcessSupervisor that removed/bugged the respawn-on-crash path; the SIGSEGV killed the supervisor itself instead of just the child; respawn is async and the read happened before it completed; crash backoff disabled.
Related errors
- Watcher supervisor did not expose a live child
- Missing ${ENTRY_PATH}; run pnpm run build:electron-vite firs
- Watcher supervisor leaked its canary directory: ${watcherCan
- SSH filesystem provider unavailable for ${target.connectionI
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/0de22ffe77527a99.
Report an issue: GitHub.