stablyai/orca · error · Error
Owned window-manager processes survived cleanup: ${evidence.
Error message
Owned window-manager processes survived cleanup: ${evidence.windowManagerGroupAfterCleanup.join('; ')} What it means
Same invariant as the IBus check but for the xfwm4 process group: after the run, stopOwnedProcessGroup(windowManagerProcess.pid) must return an empty list. Survivors mean the window manager (or a compositor child) escaped cleanup and would leak into the next test's X session.
Source
Thrown at config/scripts/run-terminal-ibus-hangul-e2e.mjs:238
path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-ibus.log')
)
copyFileSync(
windowManagerLogPath,
path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-xfwm4.log')
)
writeFileSync(
path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-processes.json'),
`${JSON.stringify(evidence, null, 2)}\n`
)
}
if (evidence.ibusGroupAfterCleanup.length > 0) {
throw new Error(
`Owned IBus processes survived cleanup: ${evidence.ibusGroupAfterCleanup.join('; ')}`
)
}
if (evidence.windowManagerGroupAfterCleanup.length > 0) {
throw new Error(
`Owned window-manager processes survived cleanup: ${evidence.windowManagerGroupAfterCleanup.join('; ')}`
)
}
return testExitCode
}
async function runOuter() {
if (process.platform !== 'linux') {
throw new Error('The native IBus Hangul E2E runner requires Linux/X11')
}
const evidenceDir = mkdtempSync(path.join(os.tmpdir(), 'orca-terminal-ime-e2e-'))
const runtimeDir = path.join(evidenceDir, 'runtime')
mkdirSync(runtimeDir, { mode: 0o700 })
mkdirSync(path.join(evidenceDir, 'config'))
mkdirSync(path.join(evidenceDir, 'cache'))
console.error(`[terminal-ime] evidence directory: ${evidenceDir}`)
View on GitHub (pinned to 1136503c6a)
Solutions
- Read the processes.json evidence file for the surviving WM PIDs.
- Start xfwm4 with --compositor=off (already set) and confirm no compositor child is spawned.
- Run the whole X11 session under xvfb-run inside a PID namespace so the group is reaped on session exit.
- Escalate stopOwnedProcessGroup to SIGKILL and re-verify for the WM group specifically.
Example fix
// before // xfwm4 child compositor survives group kill // after // run the harness under a PID namespace unshare -p --fork --mount-proc pnpm run test:e2e:terminal-ibus-hangul-native
Defensive patterns
Strategy: validation
Validate before calling
const wmSurvivors = await stopOwnedProcessGroup(windowManagerProcess.pid)
if (wmSurvivors.length > 0) {
console.error('WM survivors:', wmSurvivors)
} Try / catch
try { /* test body */ }
finally {
const wmSurvivors = await stopOwnedProcessGroup(windowManagerProcess.pid)
if (wmSurvivors.length) throw new Error(`Owned window-manager processes survived cleanup: ${wmSurvivors.join('; ')}`)
} Prevention
- Start xfwm4 with --compositor=off to avoid extra compositor children.
- Reap inside a PID namespace for deterministic cleanup.
- Make stopOwnedProcessGroup escalate to SIGKILL and re-check.
When it happens
Trigger: xfwm4 or a compositor/helper it forked survived the group-kill because it was reparented, ignored SIGTERM, or was re-activated by the X server.
Common situations: xfwm4 spawned a compositor process outside its group; the WM ignored the signal under load; the X server restarted the WM via its session manager; cgroup/PID-namespace isolation blocked the kill.
Related errors
- Owned X11 session processes survived cleanup: ${remaining.jo
- Owned IBus processes survived cleanup: ${evidence.ibusGroupA
- xfwm4 did not return a PID
- xvfb-run did not return a PID
- Failed to configure IBus Hangul ${key}: ${result.stderr.trim
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/10a1e7323824fbee.
Report an issue: GitHub.