{"record":{"id":"b941dfac70044c16","repo":"Yeachan-Heo/oh-my-codex","slug":"shutdown-shared-session-worker-owner-unavailable","errorCode":null,"errorMessage":"shutdown_shared_session_worker_owner_unavailable:${paneId}:${owner.error}","messagePattern":"shutdown_shared_session_worker_owner_unavailable:(.+?):(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/runtime.ts","lineNumber":611,"sourceCode":"  authorizedTaggedWorkerPaneIds?: Set<string>,\n): string[] {\n  const expectedOwnerId = teamPaneOwnerId.trim();\n  if (!expectedOwnerId && paneIds.length > 0) {\n    throw new Error('shutdown_shared_session_worker_owner_unavailable:missing_team_owner_id');\n  }\n\n  const authorized = new Set<string>();\n  for (const paneId of paneIds) {\n    const owner = readPaneTeamOwnerTagResult(paneId);\n    if (initiallyTaggedWorkerPaneIds?.has(paneId)\n      && (owner.status !== 'value' || owner.value !== expectedOwnerId)) {\n      throw new Error(`shutdown_shared_session_worker_owner_changed:${paneId}`);\n    }\n    if (owner.status === 'error') {\n      // A read failure is authority ambiguity only for an explicit persisted\n      // worker that topology independently identifies as a worker candidate.\n      if (canonicalWorkerPaneIds.has(paneId)) {\n        throw new Error(`shutdown_shared_session_worker_owner_unavailable:${paneId}:${owner.error}`);\n      }\n      continue;\n    }\n    if (owner.status === 'value') {\n      if (owner.value === expectedOwnerId) {\n        authorized.add(paneId);\n        authorizedTaggedWorkerPaneIds?.add(paneId);\n      } else if (canonicalWorkerPaneIds.has(paneId)) {\n        throw new Error(`shutdown_shared_session_worker_owner_changed:${paneId}`);\n      }\n      continue;\n    }\n    if (canonicalWorkerPaneIds.has(paneId)) {\n      throw new Error(`shutdown_shared_session_worker_owner_changed:${paneId}`);\n    }\n  }\n  return [...authorized];\n}","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/runtime.ts#L593-L629","documentation":"During shared-session shutdown, the runtime reads the team-owner tag of a pane that topology independently identifies as a canonical worker. The read failed (owner.status === 'error'), so authority for that worker pane cannot be established and shutdown aborts rather than risk killing a pane owned by someone else.","triggerScenarios":"Calling shutdown/converge paths that invoke collectAuthorizedSharedSessionWorkerPaneIds while a tmux user-attribute read (pane owner tag) errors for a pane present in canonicalWorkerPaneIds.","commonSituations":"tmux server hiccup or version/feature gap breaking show-options/user-attribute reads, pane destroyed mid-shutdown, or permissions issues on the tmux socket.","solutions":["Retry the shutdown once tmux settles; transient read failures are the most common cause.","Verify tmux server health and that the pane still exists (tmux list-panes -a).","Check tmux version supports the user-attribute API this library relies on.","Inspect for concurrent processes removing/retagging panes during shutdown."],"exampleFix":"// before\nconst panes = await collectAuthorizedSharedSessionWorkerPaneIds(...);\n\n// after\nlet panes;\ntry {\n  panes = await collectAuthorizedSharedSessionWorkerPaneIds(...);\n} catch (e) {\n  if (String(e.message).startsWith('shutdown_shared_session_worker_owner_unavailable:')) {\n    await sleep(500); // let tmux settle, then retry once\n    panes = await collectAuthorizedSharedSessionWorkerPaneIds(...);\n  } else throw e;\n}","handlingStrategy":"retry","validationCode":"const exists = await paneExists(paneId); // tmux list-panes check\nif (!exists) skipPane(paneId);","typeGuard":"function isOwnerUnavailableError(e: unknown, paneId?: string): e is Error {\n  return e instanceof Error && e.message.startsWith('shutdown_shared_session_worker_owner_unavailable:') && (!paneId || e.message.includes(`:${paneId}:`));\n}","tryCatchPattern":"try { await shutdownSharedSession(...); } catch (e) { if (isOwnerUnavailableError(e)) { await delay(500); return shutdownSharedSession(...); } throw e; }","preventionTips":["Verify tmux server health before shutdown","Avoid mutating pane options during team operations","Run discovery and shutdown back-to-back to minimize races"],"tags":["tmux","shutdown","shared-session","transient"],"backgroundTag":"tmux-pane-read-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}