{"record":{"id":"6819c696d02f6d32","repo":"Yeachan-Heo/oh-my-codex","slug":"shutdown-shared-session-hud-pane-identity-changed","errorCode":null,"errorMessage":"shutdown_shared_session_HUD_pane_identity_changed:${config.hud_pane_id}","messagePattern":"shutdown_shared_session_HUD_pane_identity_changed:(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/team/runtime.ts","lineNumber":5005,"sourceCode":"    // Explicit force means teardown now. Do not spend the graceful ack window\n    // waiting for interactive panes or prompt workers that will be killed below.\n    skipWorkerAcks = true;\n  } else {\n    skipWorkerAcks = useCleanFastPath;\n  }\n\n  const sessionName = config.tmux_session;\n  const sharedSessionTopology = config.worker_launch_mode === 'interactive' && sessionName.includes(':')\n    ? resolveSharedSessionShutdownTopology(sessionName, config.leader_pane_id, sanitized)\n    : null;\n  if (sharedSessionTopology?.status === 'unavailable') {\n    throw new Error(`shutdown_shared_session_topology_unavailable:${sharedSessionTopology.detail}`);\n  }\n  if (typeof config.hud_pane_id === 'string' && /^%[0-9]+$/.test(config.hud_pane_id)\n    && typeof config.hud_pane_pid === 'number' && Number.isSafeInteger(config.hud_pane_pid) && config.hud_pane_pid > 0) {\n    const persistedHudProof = readExactPaneProofSync(config.hud_pane_id);\n    if (persistedHudProof.status === 'live' && persistedHudProof.pid !== config.hud_pane_pid) {\n      throw new Error(`shutdown_shared_session_HUD_pane_identity_changed:${config.hud_pane_id}`);\n    }\n  }\n  const dispatchPolicy = resolveDispatchPolicy(manifest?.policy, config.worker_launch_mode);\n  const shutdownRequestTimes = new Map<string, string>();\n\n  if (!skipWorkerAcks) {\n    // 1. Send shutdown inbox to each worker\n    for (const w of config.workers) {\n      try {\n        const requestedAt = new Date().toISOString();\n        await writeShutdownRequest(sanitized, w.name, 'leader-fixed', cwd);\n        shutdownRequestTimes.set(w.name, requestedAt);\n        const triggerDirective = buildTriggerDirective(\n          w.name,\n          sanitized,\n          resolveInstructionStateRoot(w.worktree_path),\n        );\n        await dispatchCriticalInboxInstruction({","sourceCodeStart":4987,"sourceCodeEnd":5023,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/runtime.ts#L4987-L5023","documentation":"Identity check for the HUD pane in shared-session shutdown: the persisted hud_pane_id is live in tmux but its current PID differs from the recorded hud_pane_pid. The pane ID was reused by a different process, so the runtime refuses to kill it to avoid terminating an unrelated pane.","triggerScenarios":"Shutting down a shared-session team where the HUD pane died and tmux reused the same %pane-id for another process, while config still records the old hud_pane_pid.","commonSituations":"HUD pane crashed and pane ID got recycled; tmux server restart with pane renumbering; stale team config referencing an old HUD pane.","solutions":["Verify which process now owns the pane (tmux list-panes with pane_pid) and update or clear hud_pane_id/hud_pane_pid in team config","Kill the stale HUD pane manually if you confirm it is safe, then retry shutdown","Recreate the team if the config/state divergence is too large"],"exampleFix":"# before\nomx team shutdown myteam\n\n# after\ntmux list-panes -t myteam -F '#{pane_id} #{pane_pid}'\nomx team config set myteam hud_pane_pid <actual-pid>\nomx team shutdown myteam","handlingStrategy":"type-guard","validationCode":"const proof = readExactPaneProofSync(config.hud_pane_id);\nif (proof.status === 'live' && proof.pid !== config.hud_pane_pid) throw new Error('HUD pane identity drifted; refresh config');","typeGuard":"function hudPaneIdentityMatches(cfg: TeamConfig): boolean {\n  if (typeof cfg.hud_pane_id !== 'string' || typeof cfg.hud_pane_pid !== 'number') return true;\n  const p = readExactPaneProofSync(cfg.hud_pane_id);\n  return p.status !== 'live' || p.pid === cfg.hud_pane_pid;\n}","tryCatchPattern":"try { await shutdownTeam(t, cwd, {}); } catch (e) { if (/^shutdown_shared_session_HUD_pane_identity_changed:/.test((e as Error).message)) { await refreshHudPaneIds(t); await shutdownTeam(t, cwd, {}); } else throw e; }","preventionTips":["Never reuse or manually recycle pane IDs in team sessions","Re-check recorded pane PIDs after tmux restarts","Treat pane identity mismatches as unsafe-to-kill"],"tags":["shutdown","tmux","pane-identity"],"backgroundTag":"stale-process-identity","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}