stablyai/orca · error · Error

xfwm4 did not return a PID

Error message

xfwm4 did not return a PID

What it means

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.

Source

Thrown at config/scripts/run-terminal-ibus-hangul-e2e.mjs:141

    ibusGroupBeforeCleanup: [],
    ibusGroupAfterCleanup: [],
    playwrightPid: null,
    windowManagerPid: null,
    windowManagerGroupAfterCleanup: []
  }
  let ibusProcess
  let windowManagerProcess
  let testExitCode = 1

  try {
    configureHangulEngine()
    windowManagerProcess = spawn('xfwm4', ['--compositor=off'], {
      detached: true,
      env: process.env,
      stdio: ['ignore', windowManagerLogFd, windowManagerLogFd]
    })
    if (!windowManagerProcess.pid) {
      throw new Error('xfwm4 did not return a PID')
    }
    evidence.windowManagerPid = windowManagerProcess.pid
    console.error(`[terminal-ime] started xfwm4 PID ${windowManagerProcess.pid}`)

    ibusProcess = spawn(
      'ibus-daemon',
      ['--xim', '--verbose', '--panel=disable', '--emoji-extension=disable'],
      {
        detached: true,
        env: process.env,
        stdio: ['ignore', ibusLogFd, ibusLogFd]
      }
    )
    if (!ibusProcess.pid) {
      throw new Error('ibus-daemon did not return a PID')
    }
    evidence.ibusDaemonPid = ibusProcess.pid
    console.error(`[terminal-ime] started ibus-daemon PID ${ibusProcess.pid}`)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Install the WM: sudo apt-get install xfwm4 (or distro equivalent).
  2. Confirm `which xfwm4` resolves in the same env the harness uses (the detached spawn inherits process.env).
  3. If you intentionally run without a WM, replace the xfwm4 spawn with a stub or skip the IME-native test on hosts without one.

Example fix

// before
// xfwm4 missing -> child.pid undefined
// after
sudo apt-get install -y xfwm4
Defensive patterns

Strategy: validation

Validate before calling

const { spawnSync } = require('node:child_process')
if (spawnSync('which', ['xfwm4']).status !== 0) {
  console.error('xfwm4 not installed; apt-get install xfwm4'); process.exit(1)
}

Type guard

function hasPid(child: { pid?: number }): child is { pid: number } {
  return typeof child.pid === 'number'
}

Try / catch

const wm = spawn('xfwm4', ['--compositor=off'], { detached: true, stdio: ['ignore', fd, fd] })
wm.once('error', (e) => { console.error('xfwm4 spawn failed:', e.message) })
if (!wm.pid) throw new Error('xfwm4 did not return a PID')

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/1e60c258734acc11. Report an issue: GitHub.