Yeachan-Heo/oh-my-codex · error · Error
failed to kill tmux pane ${killTarget}: ${killed.stderr}
Error message
failed to kill tmux pane ${killTarget}: ${killed.stderr} What it means
Thrown when the tmux `kill-pane` command issued to terminate a worker pane exits non-zero; tmux's stderr is included. Additionally the follow-up liveness proof may reject (not shown here), but this specific message means the kill command itself failed — typically because the pane already disappeared or the target is malformed.
Source
Thrown at src/team/tmux-session.ts:4028
const initialTarget = await resolveTarget();
if (!initialTarget) return;
if (await isWorkerAliveAsync(sessionName, workerIndex, workerPaneId, expectedPanePid, expectedTeamOwnerId, hudPaneId, resolveTarget) !== 'alive') return;
await runTmuxAsync(['send-keys', '-t', initialTarget, 'C-c']);
await sleep(1000);
if (await isWorkerAliveAsync(sessionName, workerIndex, workerPaneId, expectedPanePid, expectedTeamOwnerId, hudPaneId, resolveTarget) === 'alive') {
const exitTarget = await resolveTarget();
if (exitTarget) {
await runTmuxAsync(['send-keys', '-t', exitTarget, 'C-d']);
await sleep(1000);
}
}
if (await isWorkerAliveAsync(sessionName, workerIndex, workerPaneId, expectedPanePid, expectedTeamOwnerId, hudPaneId, resolveTarget) === 'alive') {
const killTarget = await resolveTarget();
if (!killTarget) return;
const killed = await runTmuxAsync(['kill-pane', '-t', killTarget]);
if (!killed.ok) throw new Error(`failed to kill tmux pane ${killTarget}: ${killed.stderr}`);
const absence = await readExactPaneProof(killTarget);
if (absence.status === 'unavailable') throw new ExactPaneProofUnavailableError(absence);
if (absence.status !== 'gone') throw new Error(`tmux pane remains live after kill: ${killTarget}`);
}
}
// Explicit pane targets require frozen PID, canonical Team owner, and HUD
// exclusion. A successful kill is only accepted after a fresh absence proof.
export function killWorkerByPaneId(
workerPaneId: string,
expectedPanePid?: number,
leaderPaneId?: string,
expectedTeamOwnerId?: string,
hudPaneId?: string,
): void {
const expectedOwner = typeof expectedTeamOwnerId === 'string' ? expectedTeamOwnerId.trim() : '';
if (!hasExplicitWorkerPaneId(workerPaneId)View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Treat 'no such pane' / 'can't find session' stderr as success — the pane is already gone; skip or ignore
- Re-check liveness (isWorkerAliveAsync) immediately before kill to shrink the race window
- Serialize cleanup handlers so kill runs exactly once
- Re-resolve the target right before killing instead of reusing a cached one
Example fix
// before
const killed = await runTmuxAsync(['kill-pane', '-t', target]);
if (!killed.ok) throw new Error(killed.stderr);
// after
const killed = await runTmuxAsync(['kill-pane', '-t', target]);
if (!killed.ok && !/no such pane|can't find session/.test(killed.stderr)) {
throw new Error(killed.stderr);
} Defensive patterns
Strategy: try-catch
Validate before calling
if ((await isWorkerAliveAsync(sessionName, idx, paneId)) !== 'alive') return; // nothing to kill
Try / catch
try { await killWorkerPane(target); } catch (err) { if (!/no such pane|can't find session/.test(String(err))) throw err; } Prevention
- Treat already-gone panes as successfully killed
- Serialize cleanup so kill-pane runs once
- Re-resolve the target immediately before killing
When it happens
Trigger: Calling the worker-kill routine while the pane is concurrently closing (agent exits on its own), the session is already dead, or resolveTarget returns a stale/malformed target string at kill time.
Common situations: Race between worker process exit and orchestrator cleanup; kill issued during tmux server shutdown; double-kill from overlapping cleanup handlers; stale pane id from a previous session.
Related errors
- failed to kill tmux pane ${finalProof.paneId}: ${result.stde
- invalid auth slot path
- ${label} is not a file: ${path}
- Refusing to overwrite existing ${repoRelative(cwd, missionPa
- preLaunch setup finalization failed
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/55d9504759b92747.
Report an issue: GitHub.