stablyai/orca · error · Error
xvfb-run did not return a PID
Error message
xvfb-run did not return a PID
What it means
runOuter() spawns `xvfb-run` to provide an isolated X server for the inner session. If spawn() returns no pid, xvfb-run could not be forked (binary missing, PATH stripped, fork failure) and the inner session would never start. The harness aborts because every subsequent step depends on a working display.
Source
Thrown at config/scripts/run-terminal-ibus-hangul-e2e.mjs:286
{
cwd: projectDir,
detached: true,
env: {
...process.env,
GTK_IM_MODULE: 'ibus',
IBUS_ENABLE_SYNC_MODE: '1',
LANG: process.env.LANG || 'C.UTF-8',
QT_IM_MODULE: 'ibus',
XDG_CACHE_HOME: path.join(evidenceDir, 'cache'),
XDG_CONFIG_HOME: path.join(evidenceDir, 'config'),
XDG_RUNTIME_DIR: runtimeDir,
XMODIFIERS: '@im=ibus'
},
stdio: 'inherit'
}
)
if (!sessionProcess.pid) {
throw new Error('xvfb-run did not return a PID')
}
console.error(`[terminal-ime] started isolated X11 session PID ${sessionProcess.pid}`)
const exitCode = await waitForExit(sessionProcess)
const remaining = await stopOwnedProcessGroup(sessionProcess.pid)
if (remaining.length > 0) {
throw new Error(`Owned X11 session processes survived cleanup: ${remaining.join('; ')}`)
}
return exitCode
}
const insideSession = process.argv[2] === insideSessionFlag
try {
if (insideSession && !process.argv[3]) {
throw new Error(`${insideSessionFlag} requires an evidence directory argument`)
}
process.exitCode = insideSession ? await runInsideSession(process.argv[3]) : await runOuter()
} catch (error) {
console.error(`[terminal-ime] ${error instanceof Error ? error.message : String(error)}`)View on GitHub (pinned to 1136503c6a)
Solutions
- Install Xvfb wrapper: sudo apt-get install xvfb (Debian/Ubuntu) or xorg-x11-server-Xvfb (Fedora).
- Confirm `which xvfb-run` resolves in the env the harness inherits.
- If only Xvfb is available, replace the xvfb-run invocation with an explicit Xvfb + DISPLAY export.
Example fix
// before // xvfb-run missing -> no pid // after sudo apt-get install -y xvfb
Defensive patterns
Strategy: validation
Validate before calling
const { spawnSync } = require('node:child_process')
if (spawnSync('which', ['xvfb-run']).status !== 0) {
console.error('xvfb-run not installed; apt-get install xvfb'); process.exit(1)
} Type guard
function hasPid(child: { pid?: number }): child is { pid: number } {
return typeof child.pid === 'number'
} Try / catch
const session = spawn('xvfb-run', args, { detached: true, env, stdio: 'inherit' })
session.once('error', (e) => { console.error('xvfb-run spawn failed:', e.message) })
if (!session.pid) throw new Error('xvfb-run did not return a PID') Prevention
- Preflight `which xvfb-run` in the harness.
- Listen for the spawn 'error' event to report ENOENT cleanly.
- Include xvfb in the base CI image.
When it happens
Trigger: xvfb-run is not installed or not on PATH; spawn() fork fails due to resource limits; the env passed to spawn drops PATH.
Common situations: Minimal CI image without xorg-xserver-xvfb or xserver-xorg-video-dummy; container where PATH was reset; running on a host that uses startx/Xvfb directly instead of the wrapper.
Related errors
- xfwm4 did not return a PID
- Owned X11 session processes survived cleanup: ${remaining.jo
- ibus-daemon did not return a PID
- Owned window-manager processes survived cleanup: ${evidence.
- Failed to configure IBus Hangul ${key}: ${result.stderr.trim
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/0fe851b258c45ccd.
Report an issue: GitHub.