{"record":{"id":"38114c64a9438014","repo":"stablyai/orca","slug":"owned-ibus-processes-survived-cleanup-evidence","errorCode":null,"errorMessage":"Owned IBus processes survived cleanup: ${evidence.ibusGroupAfterCleanup.join('; ')}","messagePattern":"Owned IBus processes survived cleanup: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/run-terminal-ibus-hangul-e2e.mjs","lineNumber":233,"sourceCode":"    closeSync(ibusLogFd)\n    closeSync(windowManagerLogFd)\n    mkdirSync(path.join(projectDir, 'test-results'), { recursive: true })\n    copyFileSync(\n      ibusLogPath,\n      path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-ibus.log')\n    )\n    copyFileSync(\n      windowManagerLogPath,\n      path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-xfwm4.log')\n    )\n    writeFileSync(\n      path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-processes.json'),\n      `${JSON.stringify(evidence, null, 2)}\\n`\n    )\n  }\n\n  if (evidence.ibusGroupAfterCleanup.length > 0) {\n    throw new Error(\n      `Owned IBus processes survived cleanup: ${evidence.ibusGroupAfterCleanup.join('; ')}`\n    )\n  }\n  if (evidence.windowManagerGroupAfterCleanup.length > 0) {\n    throw new Error(\n      `Owned window-manager processes survived cleanup: ${evidence.windowManagerGroupAfterCleanup.join('; ')}`\n    )\n  }\n  return testExitCode\n}\n\nasync function runOuter() {\n  if (process.platform !== 'linux') {\n    throw new Error('The native IBus Hangul E2E runner requires Linux/X11')\n  }\n\n  const evidenceDir = mkdtempSync(path.join(os.tmpdir(), 'orca-terminal-ime-e2e-'))\n  const runtimeDir = path.join(evidenceDir, 'runtime')","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/run-terminal-ibus-hangul-e2e.mjs#L215-L251","documentation":"After the test runs, the finally block calls stopOwnedProcessGroup(ibusProcess.pid) to kill the whole IBus process group and returns surviving member PIDs. If any survive, the harness fails the run — a leaked IME daemon would corrupt subsequent tests or pollute the host. The surviving PID list is included in the message and in test-results/terminal-ibus-hangul-native-processes.json.","triggerScenarios":"ibus-daemon or one of its helper processes (ibus-x11, ibus-portal, the hangul engine) was reparented out of the process group, refused SIGTERM/SIGKILL, or was re-spawned by the session manager after the group kill.","commonSituations":"ibus-daemon restarts itself via DBus activation after being killed; a process escaped the group via setsid; container/cgroup shielding blocks the signal; slow shutdown exceeding the kill grace period.","solutions":["Inspect test-results/terminal-ibus-hangul-native-processes.json for the surviving PIDs and their names.","Disable DBus autostart for ibus-daemon in the session env (IBUS_DAEMON_NO_RESTART / unset the .service autostart) so it cannot respawn.","Make stopOwnedProcessGroup escalate to SIGKILL after a short grace and re-check; if it already does, widen the grace window.","Run inside a PID namespace (unshare -p) so the whole tree is reaped deterministically."],"exampleFix":"// before\n// ibus-daemon respawns via DBus activation after group kill\n// after\n// in the session env block, disable autostart:\nIBUS_DISABLE_AUTOSTART: '1'","handlingStrategy":"validation","validationCode":"// post-cleanup leak guard with context\nconst remaining = await stopOwnedProcessGroup(ibusProcess.pid)\nif (remaining.length > 0) {\n  console.error('IBus survivors:', remaining, '(check processes.json)')\n  // optionally escalate: pkill -9 each\n}","typeGuard":null,"tryCatchPattern":"try { /* test body */ }\nfinally {\n  const survivors = await stopOwnedProcessGroup(ibusProcess.pid)\n  if (survivors.length) throw new Error(`Owned IBus processes survived cleanup: ${survivors.join('; ')}`)\n}","preventionTips":["Disable DBus autostart for ibus-daemon in the session env to prevent respawn.","Run the session inside a PID namespace so the whole tree is reaped.","Have stopOwnedProcessGroup escalate SIGTERM -> SIGKILL and re-verify."],"tags":["ibus","process-cleanup","process-group","leak","linux","e2e"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}