{"record":{"id":"ef7466df764d16f5","repo":"stablyai/orca","slug":"watcher-supervisor-did-not-expose-a-live-child","errorCode":null,"errorMessage":"Watcher supervisor did not expose a live child","messagePattern":"Watcher supervisor did not expose a live child","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/runtime-file-watcher-fault-harness.mjs","lineNumber":132,"sourceCode":"        delivery: { includeDirectoryMetadata: true, maxEventsPerBatch: 200 },\n        onInterruption: () => resolveInterruption()\n      }\n    )\n    watcherCanaryDir = supervisor.canaryDir\n\n    const beforeEvent = nextMatchingEvent(\n      (listener) => {\n        eventListener = listener\n      },\n      (event) => event.path === join(rootPath, 'before.txt'),\n      'pre-crash watch event'\n    )\n    await writeFile(join(rootPath, 'before.txt'), 'before')\n    await Promise.race([beforeEvent, watcherError])\n\n    const firstChildPid = supervisor.child?.pid\n    if (!firstChildPid) {\n      throw new Error('Watcher supervisor did not expose a live child')\n    }\n    process.kill(firstChildPid, 'SIGSEGV')\n    await Promise.race([interrupted, watcherError])\n\n    const replacementChildPid = supervisor.child?.pid\n    if (!replacementChildPid || replacementChildPid === firstChildPid) {\n      throw new Error('Watcher supervisor did not replace the faulted child')\n    }\n    const afterEvent = nextMatchingEvent(\n      (listener) => {\n        eventListener = listener\n      },\n      (event) => event.path === join(rootPath, 'after.txt'),\n      'post-crash watch event'\n    )\n    await writeFile(join(rootPath, 'after.txt'), 'after')\n    await Promise.race([afterEvent, watcherError])\n","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/runtime-file-watcher-fault-harness.mjs#L114-L150","documentation":"The harness grabs supervisor.child?.pid as the firstChildPid before sending SIGSEGV. If the supervisor has no live child (child is null or pid is undefined), the fault-injection step cannot proceed — there is nothing to crash. This usually means the supervisor failed to spawn its watcher child during setup.","triggerScenarios":"WatcherProcessSupervisor started but its forked @parcel/watcher child exited immediately or was never spawned, so supervisor.child is null/undefined by the time the harness reads .pid.","commonSituations":"The watcher child crashed on startup (native module load failure — @parcel/watcher missing or wrong ABI); the supervisor was constructed in a mode that defers spawning; a race where the child exited between construction and the pid read.","solutions":["Check the supervisor's spawn error path — log supervisor.child and any error event before the SIGSEGV step.","Rebuild native modules for the current Electron/Node ABI (pnpm run build:electron-vite + electron-rebuild).","Confirm @parcel/watcher is installed and loadable: node -e \"require('@parcel/watcher')\".","Ensure the supervisor is fully started (await its ready signal) before reading child.pid."],"exampleFix":"// before\nconst firstChildPid = supervisor.child?.pid\nif (!firstChildPid) throw new Error(...)\n// after\nawait supervisor.whenReady?.()  // or the equivalent ready promise\nconst firstChildPid = supervisor.child?.pid\nif (!firstChildPid) throw new Error(...)","handlingStrategy":"validation","validationCode":"if (!supervisor?.child || typeof supervisor.child.pid !== 'number') {\n  console.error('Watcher supervisor has no live child; check native module load')\n  process.exit(1)\n}","typeGuard":"function hasLiveChild(s: { child?: { pid?: number } | null }): s is { child: { pid: number } } {\n  return !!s?.child && typeof s.child.pid === 'number'\n}","tryCatchPattern":"if (!hasLiveChild(supervisor)) {\n  throw new Error('Watcher supervisor did not expose a live child')\n}","preventionTips":["Await the supervisor's ready signal before reading child.pid.","Verify @parcel/watcher loads against the current Node/Electron ABI.","Attach an 'error'/'exit' listener to the child to catch early deaths with context."],"tags":["file-watcher","parcel","child-process","native-module","fault-injection"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}