{"record":{"id":"1e60c258734acc11","repo":"stablyai/orca","slug":"xfwm4-did-not-return-a-pid","errorCode":null,"errorMessage":"xfwm4 did not return a PID","messagePattern":"xfwm4 did not return a PID","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/run-terminal-ibus-hangul-e2e.mjs","lineNumber":141,"sourceCode":"    ibusGroupBeforeCleanup: [],\n    ibusGroupAfterCleanup: [],\n    playwrightPid: null,\n    windowManagerPid: null,\n    windowManagerGroupAfterCleanup: []\n  }\n  let ibusProcess\n  let windowManagerProcess\n  let testExitCode = 1\n\n  try {\n    configureHangulEngine()\n    windowManagerProcess = spawn('xfwm4', ['--compositor=off'], {\n      detached: true,\n      env: process.env,\n      stdio: ['ignore', windowManagerLogFd, windowManagerLogFd]\n    })\n    if (!windowManagerProcess.pid) {\n      throw new Error('xfwm4 did not return a PID')\n    }\n    evidence.windowManagerPid = windowManagerProcess.pid\n    console.error(`[terminal-ime] started xfwm4 PID ${windowManagerProcess.pid}`)\n\n    ibusProcess = spawn(\n      'ibus-daemon',\n      ['--xim', '--verbose', '--panel=disable', '--emoji-extension=disable'],\n      {\n        detached: true,\n        env: process.env,\n        stdio: ['ignore', ibusLogFd, ibusLogFd]\n      }\n    )\n    if (!ibusProcess.pid) {\n      throw new Error('ibus-daemon did not return a PID')\n    }\n    evidence.ibusDaemonPid = ibusProcess.pid\n    console.error(`[terminal-ime] started ibus-daemon PID ${ibusProcess.pid}`)","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/run-terminal-ibus-hangul-e2e.mjs#L123-L159","documentation":"The harness spawns xfwm4 (the Xfwm window manager, used as a minimal WM so IME focus events behave realistically) detached. Node's spawn returns a ChildProcess whose pid is undefined if the process could not be forked (ENOKE/EPERM) — or spawnSync emits an error event. The guard treats a missing pid as fatal because the rest of the IME flow assumes a composited X session exists.","triggerScenarios":"xfwm4 is not on PATH, not executable, or cannot fork because the X display is not yet ready; spawn() sets child.pid only on successful fork, so its absence means the binary was never launched.","commonSituations":"xfwm4 package not installed on the CI/dev image; PATH not inherited into the detached spawn; the Xvfb display from xvfb-run has not started yet; wrong architecture binary.","solutions":["Install the WM: sudo apt-get install xfwm4 (or distro equivalent).","Confirm `which xfwm4` resolves in the same env the harness uses (the detached spawn inherits process.env).","If you intentionally run without a WM, replace the xfwm4 spawn with a stub or skip the IME-native test on hosts without one."],"exampleFix":"// before\n// xfwm4 missing -> child.pid undefined\n// after\nsudo apt-get install -y xfwm4","handlingStrategy":"validation","validationCode":"const { spawnSync } = require('node:child_process')\nif (spawnSync('which', ['xfwm4']).status !== 0) {\n  console.error('xfwm4 not installed; apt-get install xfwm4'); process.exit(1)\n}","typeGuard":"function hasPid(child: { pid?: number }): child is { pid: number } {\n  return typeof child.pid === 'number'\n}","tryCatchPattern":"const wm = spawn('xfwm4', ['--compositor=off'], { detached: true, stdio: ['ignore', fd, fd] })\nwm.once('error', (e) => { console.error('xfwm4 spawn failed:', e.message) })\nif (!wm.pid) throw new Error('xfwm4 did not return a PID')","preventionTips":["Add `which xfwm4` to the harness preflight.","Listen for the spawn 'error' event to surface ENOENT before checking pid.","Document the host dependencies (xfwm4, xvfb, ibus) in the script header."],"tags":["x11","window-manager","spawn","linux","e2e"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}