Yeachan-Heo/oh-my-codex · warning · Error
tmux pane is not proven live: ${paneId}
Error message
tmux pane is not proven live: ${paneId} What it means
requireLiveExactPaneSync demands a fresh global snapshot proving the pane is live before any destructive operation. `gone' means tmux explicitly reported the pane as dead/deleted — callers should treat this as 'already cleaned' rather than an actual failure, but the guard throws so no action is taken.
Source
Thrown at src/team/tmux-session.ts:585
const hudMatches = !topology.error && topology.panes.filter((pane) => pane.paneId === debt.pane_id
&& hudPaneMatchesOwner(pane, { leaderPaneId: debt.hud_owner_leader_pane_id })).length === 1;
if (!hudMatches) throw new Error(`restored_hud_cleanup_debt_unresolved:${debt.pane_id}`);
const finalProof = readExactPaneProofSync(debt.pane_id);
if (finalProof.status !== 'live' || finalProof.pid !== debt.pane_pid) {
throw new Error(`restored_hud_cleanup_debt_unresolved:${debt.pane_id}`);
}
removeRestoredHudCleanupDebtSync(record.path);
}
/**
* Kill only a pane that a fresh global snapshot proves live. Callers treat
* gone/dead rows as already cleaned and unavailable snapshots as fail-closed.
*/
function requireLiveExactPaneSync(paneId: string, expectedPid?: number): string {
const proof = readExactPaneProofSync(paneId);
if (proof.status === 'unavailable') throw new ExactPaneProofUnavailableError(proof);
if (proof.status === 'gone') throw new Error(`tmux pane is not proven live: ${paneId}`);
if (expectedPid !== undefined && proof.pid !== expectedPid) {
throw new Error(`tmux pane identity changed: ${paneId}`);
}
return proof.paneId;
}
function killExactPaneSync(paneId: string, expectedPid?: number, assertAuthorization?: () => void): void {
const proof = readExactPaneProofSync(paneId);
if (proof.status === 'unavailable') throw new ExactPaneProofUnavailableError(proof);
if (proof.status === 'gone') return;
if (expectedPid !== undefined && proof.pid !== expectedPid) {
throw new Error(`tmux pane identity changed: ${paneId}`);
}
assertAuthorization?.();
// Authorization can read tmux. Re-prove immediately after it so a recycled
// pane ID cannot be targeted by the subsequent kill.
const finalProof = readExactPaneProofSync(proof.paneId);
if (finalProof.status === 'unavailable') throw new ExactPaneProofUnavailableError(finalProof);View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Catch this and treat as success/no-op when cleaning up (pane already gone)
- Avoid retry storms: check whether your orchestrator already killed the pane
- No repair needed if the goal was removal
Example fix
// before
requireLiveExactPaneSync(paneId);
// after
try { requireLiveExactPaneSync(paneId); }
catch (e) { if (!/not proven live/.test(e.message)) throw e; /* already gone */ } Defensive patterns
Strategy: try-catch
Validate before calling
const proof = readExactPaneProofSync(paneId); if (proof.status === 'gone') return; // already cleaned
Type guard
const paneIsGone = (p: ExactPaneProof): boolean => p.status === 'gone';
Try / catch
catch (e) { if (/not proven live/.test(e.message)) return; /* idempotent success */ throw e; } Prevention
- Make cleanup idempotent and treat 'gone' as success
When it happens
Trigger: Calling kill/cleanup paths (requireLiveExactPaneSync) for a pane that tmux already deleted: normal shutdown race where the pane exited first, or a previous cleanup already killed it.
Common situations: Idempotent cleanup retries; agent pane finished and closed before the sweeper ran; double-shutdown paths.
Related errors
- ${label} not found: ${path}
- shutdown_shared_session_${kind.replaceAll(' ', '_')}_proof_u
- shutdown_${scope}_${kind.replaceAll(' ', '_')}_identity_chan
- failed to capture tmux source authority: ${result.stderr}
- tmux pane is not proven live: ${normalizedLeaderPaneId}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/730613173e0df104.
Report an issue: GitHub.