stablyai/orca · error · Error

Owned X11 session processes survived cleanup: ${remaining.jo

Error message

Owned X11 session processes survived cleanup: ${remaining.join('; ')}

What it means

After the inner session exits, runOuter() calls stopOwnedProcessGroup(sessionProcess.pid) to reap the whole xvfb-run tree (Xvfb, the inner session's IBus, xfwm4, etc.). Survivors would leak X servers and DBus daemons onto the host. The surviving PID list is included in the message.

Source

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

        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)}`)
  process.exitCode = 1
}

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Inspect the surviving PIDs (the message lists them) and identify which component escapes.
  2. Run the outer harness inside a PID namespace so xvfb-run's entire tree is reaped on session exit.
  3. Disable DBus/session autostart of ibus and other helpers inside the inner session env.
  4. Ensure stopOwnedProcessGroup escalates to SIGKILL and re-checks for the session group.

Example fix

// before
pnpm run test:e2e:terminal-ibus-hangul-native
// after
unshare -p --fork --mount-proc pnpm run test:e2e:terminal-ibus-hangul-native
Defensive patterns

Strategy: validation

Validate before calling

const remaining = await stopOwnedProcessGroup(sessionProcess.pid)
if (remaining.length > 0) {
  console.error('X11 session survivors:', remaining)
}

Try / catch

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('; ')}`)

Prevention

When it happens

Trigger: A process spawned inside the X11 session escaped the process group (setsid, reparented to init) or ignored the kill — e.g. Xvfb itself, a DBus daemon, or a re-activated ibus-daemon.

Common situations: xvfb-run's Xvfb child runs in its own session; DBus autostarts a session bus that escapes the group; a long-lived helper started with setsid; cgroup isolation blocks SIGKILL.

Related errors


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