Yeachan-Heo/oh-my-codex · error · Error
shutdown_shared_session_${kind.replaceAll(' ', '_')}_identit
Error message
shutdown_shared_session_${kind.replaceAll(' ', '_')}_identity_changed:${paneId} What it means
Thrown during shared-session shutdown when the live pane proof's PID no longer matches the expected (persisted) PID. It protects against killing a process that now occupies the same pane id but is not the original HUD/restore-leader process.
Source
Thrown at src/team/runtime.ts:5186
paneId: string;
pid: number;
owner: string | null;
};
const freezeSharedPaneAuthorization = (
paneId: string,
kind: 'HUD pane' | 'restore leader pane',
expectedPid?: number | null,
): FrozenSharedPaneAuthorization => {
const proof = readExactPaneProofSync(paneId);
if (proof.status !== 'live') {
throw new Error(`shutdown_shared_session_${kind.replaceAll(' ', '_')}_proof_unavailable:${paneId}`);
}
if (typeof expectedPid === 'number') {
if (!Number.isSafeInteger(expectedPid) || expectedPid <= 0) {
throw new Error(`shutdown_shared_session_${kind.replaceAll(' ', '_')}_pid_missing:${paneId}`);
}
if (proof.pid !== expectedPid) {
throw new Error(`shutdown_shared_session_${kind.replaceAll(' ', '_')}_identity_changed:${paneId}`);
}
}
const owner = readPaneTeamOwnerTagResult(paneId);
if (owner.status === 'error') {
throw new Error(`shutdown_shared_session_${kind.replaceAll(' ', '_')}_owner_unavailable:${paneId}:${owner.error}`);
}
if (owner.status !== 'value' || !tmuxPaneOwnerId || owner.value !== tmuxPaneOwnerId) {
throw new Error(`shutdown_shared_session_${kind.replaceAll(' ', '_')}_owner_changed:${paneId}`);
}
return { paneId, pid: proof.pid, owner: owner.value };
};
const assertSharedPaneAuthorizationContinuous = (
authorization: FrozenSharedPaneAuthorization,
kind: 'HUD pane' | 'restore leader pane',
): void => {
const scope = sharedSessionTopology ? 'shared_session' : 'detached_session';
const proof = readExactPaneProofSync(authorization.paneId);
if (proof.status !== 'live' || proof.pid !== authorization.pid) {View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Reset persisted pane ids/PIDs (hud_pane_id, hud_pane_pid) so shutdown re-discovers panes instead of trusting stale ids
- Kill the orphaned/foreign pane manually and restart the team session
- Verify no other tool is respawning panes inside the shared session
Defensive patterns
Strategy: validation
Validate before calling
const live = readExactPaneProofSync(paneId); if (live.status !== 'live' || (expectedPid && live.pid !== expectedPid)) { /* drop pin */ } Try / catch
catch (e) { if (String(e.message).includes('_identity_changed:')) clearPersistedPaneIds(); } Prevention
- Treat pane id + pid pairs as opaque and short-lived
- Re-derive pane pins after any respawn
When it happens
Trigger: freezeSharedPaneAuthorization succeeds in reading a live proof, but proof.pid !== expectedPid — tmux reused the pane id for a new process, or the recorded PID is from a previous run.
Common situations: tmux pane was respawned (respawn-pane, automatic-rename cycles) reusing the %id; leftover config from a crashed previous session; PID wraparound after long uptime.
Related errors
- shutdown_shared_session_worker_owner_unavailable:${paneId}:$
- shutdown_shared_session_topology_unavailable:${sharedSession
- shutdown_shared_session_HUD_pane_identity_changed:${config.h
- shutdown_shared_session_worker_target_invalid:${sharedWorker
- shutdown_shared_session_${kind.replaceAll(' ', '_')}_proof_u
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/c2b803e9f6272635.
Report an issue: GitHub.