{"record":{"id":"891add8136cc641b","repo":"Yeachan-Heo/oh-my-codex","slug":"startup-worker-pane-pid-unavailable-paneid","errorCode":null,"errorMessage":"startup_worker_pane_pid_unavailable:${paneId}","messagePattern":"startup_worker_pane_pid_unavailable:(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/runtime.ts","lineNumber":3842,"sourceCode":"      const identity: WorkerInfo = {\n        name: bootstrapPlan.workerName,\n        index: workerIndex,\n        role: bootstrapPlan.workerRole,\n        worker_cli: bootstrapPlan.workerCli,\n        assigned_tasks: bootstrapPlan.workerTasks.map((task) => task.id),\n        working_dir: workerWorkspace.cwd,\n        worktree_repo_root: workerWorkspace.worktreeRepoRoot,\n        worktree_path: workerWorkspace.worktreePath,\n        worktree_branch: workerWorkspace.worktreeBranch,\n        worktree_detached: workerWorkspace.worktreeDetached,\n        worktree_created: workerWorkspace.worktreeCreated,\n        team_state_root: teamStateRoot,\n      };\n\n      const persistedPanePid = config?.workers[workerIndex - 1]?.pid;\n      if (workerLaunchMode === 'interactive' && paneId) {\n        if (typeof persistedPanePid !== 'number' || !Number.isSafeInteger(persistedPanePid) || persistedPanePid <= 0) {\n          throw new Error(`startup_worker_pane_pid_unavailable:${paneId}`);\n        }\n        const paneProof = readExactPaneProofSync(paneId);\n        if (paneProof.status !== 'live' || paneProof.pid !== persistedPanePid) {\n          throw new Error(`startup_worker_pane_identity_changed:${paneId}`);\n        }\n        identity.pid = persistedPanePid;\n      } else if (typeof persistedPanePid === 'number') {\n        identity.pid = persistedPanePid;\n      }\n\n      if (paneId) identity.pane_id = paneId;\n\n      if (config?.workers[workerIndex - 1]) {\n        config.workers[workerIndex - 1].pid = identity.pid;\n        config.workers[workerIndex - 1].pane_id = paneId;\n        config.workers[workerIndex - 1].role = bootstrapPlan.workerRole;\n        config.workers[workerIndex - 1].worker_cli = bootstrapPlan.workerCli;\n        config.workers[workerIndex - 1].assigned_tasks = bootstrapPlan.workerTasks.map((task) => task.id);","sourceCodeStart":3824,"sourceCodeEnd":3860,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/runtime.ts#L3824-L3860","documentation":"In interactive mode, each worker pane's PID must be recorded in the persisted team config before startup proceeds. This error means the config's workers[i-1].pid is missing, not a safe positive integer, so the runtime cannot bind identity to the pane.","triggerScenarios":"Interactive worker startup where paneId exists but config.workers[workerIndex-1].pid is undefined, 0, negative, a float, or an unsafe integer — e.g., config saved before pane PIDs were captured, or restored from an older state file without pid fields.","commonSituations":"Resuming a team from a stale or older-format config file; a crash between pane creation and config persistence; concurrent leaders racing to write the config.","solutions":["Clean up the stale team (detectAndCleanStaleTeam or manual cleanup) and start fresh so pids are persisted correctly","Ensure only one leader starts the team; avoid concurrent startups sharing state","If persisting configs yourself, always write worker pid as a positive safe integer"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const workers = config?.workers ?? [];\nconst pidsValid = workers.length >= workerCount && workers.slice(0, workerCount).every(w =>\n  typeof w?.pid === 'number' && Number.isSafeInteger(w.pid) && w.pid > 0);\nif (!pidsValid) await cleanupStaleTeam();","typeGuard":"const hasPersistedWorkerPid = (w: unknown): w is { pid: number } =>\n  typeof (w as { pid?: unknown })?.pid === 'number' &&\n  Number.isSafeInteger((w as { pid: number }).pid) && (w as { pid: number }).pid > 0;","tryCatchPattern":"try { await resumeTeam(); } catch (e) { if (/^startup_worker_pane_pid_unavailable/.test(String((e as Error).message))) { await teardownAndRestartFresh(); return; } throw e; }","preventionTips":["Always start from clean state; don't resume configs from older versions","Persist worker pids immediately after pane creation","Avoid killing tmux between startup steps"],"tags":["team-mode","tmux","pid","config-validation"],"backgroundTag":"stale-state-validation-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}