{"record":{"id":"7ea2a871e6d61f4c","repo":"Yeachan-Heo/oh-my-codex","slug":"tmux-pane-team-owner-changed-workerpaneid-d","errorCode":null,"errorMessage":"tmux pane team owner changed: ${workerPaneId}: ${detail}","messagePattern":"tmux pane team owner changed: (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/team/tmux-session.ts","lineNumber":1156,"sourceCode":"  const pinnedPid = expectedPanePid;\n  const expectedOwner = typeof expectedTeamOwnerId === 'string' ? expectedTeamOwnerId.trim() : '';\n  const canonicalHudPaneId = typeof hudPaneId === 'string' ? hudPaneId.trim() : '';\n  let lastResolvedPid: number | undefined;\n  const resolveTarget: AsyncPaneTargetResolver = async () => {\n    if (typeof pinnedPid !== 'number' || !Number.isSafeInteger(pinnedPid) || pinnedPid <= 0) return null;\n    if (!expectedOwner) return null;\n    if (canonicalHudPaneId && workerPaneId === canonicalHudPaneId) {\n      throw new Error(`tmux worker pane is HUD target: ${workerPaneId}`);\n    }\n    const proof = await readExactPaneProof(workerPaneId);\n    if (proof.status !== 'live') return null;\n    if (proof.pid !== pinnedPid) {\n      throw new Error(`tmux pane identity changed: ${workerPaneId}`);\n    }\n    const owner = readPaneTeamOwnerTagResult(proof.paneId);\n    if (owner.status !== 'value' || owner.value !== expectedOwner) {\n      const detail = owner.status === 'error' ? owner.error : 'missing';\n      throw new Error(`tmux pane team owner changed: ${workerPaneId}: ${detail}`);\n    }\n    // The option read is untrusted and can race pane ID reuse. Its immediately\n    // adjacent PID proof authorizes the following capture/control/input effect.\n    const finalProof = await readExactPaneProof(workerPaneId);\n    if (finalProof.status !== 'live') return null;\n    if (finalProof.pid !== pinnedPid) {\n      throw new Error(`tmux pane identity changed: ${workerPaneId}`);\n    }\n    lastResolvedPid = finalProof.pid;\n    return finalProof.paneId;\n  };\n  resolveTarget.lastResolvedPid = () => lastResolvedPid;\n  return resolveTarget;\n}\n\ntype AsyncPaneTargetResolver = (() => Promise<string | null>) & {\n  lastResolvedPid?: () => number | undefined;\n};","sourceCodeStart":1138,"sourceCodeEnd":1174,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/tmux-session.ts#L1138-L1174","documentation":"The tmux user option carrying the team owner tag on the pane either is missing, errored on read, or no longer equals the expected owner. This proves the pane now belongs to a different team/owner (or the tag was stripped), so the orchestrator refuses to act on it.","triggerScenarios":"readPaneTeamOwnerTagResult returns status 'error' (tmux read failure) or a value different from expectedOwner; e.g. the pane was retagged by another team session or the option was cleared with tmux set-option -u.","commonSituations":"Two team sessions targeting the same panes; manually clearing tmux user options; session restore tools that drop user options.","solutions":["Inspect the tag: tmux display-message -p -t <paneId> '#{?@...,...}' or tmux show-options -p -t <paneId>","Recreate the pane through the team session so owner tags are set correctly","Avoid running multiple team orchestrators over the same tmux panes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const owner = readPaneTeamOwnerTagResult(paneId);\nif (owner.status !== 'value' || owner.value !== expectedOwner) { /* pane not ours; skip */ }","typeGuard":"function isOwnerChangedError(e: unknown): e is Error {\n  return e instanceof Error && e.message.startsWith('tmux pane team owner changed');\n}","tryCatchPattern":"try { await op(resolver); } catch (e) { if (isOwnerChangedError(e)) abortTeamRun(); else throw e; }","preventionTips":["Run one team orchestrator per set of panes","Never clear tmux user options (@-prefixed) on team panes","Re-create panes via the session API rather than reusing tagged panes from other teams"],"tags":["tmux","owner-tag","session-conflict"],"backgroundTag":"resource-ownership-conflict","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}