{"record":{"id":"172c4ebd485f4c46","repo":"Yeachan-Heo/oh-my-codex","slug":"worker-notify-failed","errorCode":null,"errorMessage":"worker_notify_failed","messagePattern":"worker_notify_failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/runtime.ts","lineNumber":4787,"sourceCode":"      if (outcome.ok) break;\n      if (attempt < maxAssignRetries && config.worker_launch_mode === 'interactive' && config.tmux_session) {\n        if (dismissTrustPromptIfPresent(config.tmux_session, workerInfo.index, workerInfo.pane_id, workerInfo.pid, config.tmux_pane_owner_id ?? undefined, config.hud_pane_id ?? undefined)) {\n          waitForWorkerReady(\n            config.tmux_session,\n            workerInfo.index,\n            resolveWorkerReadyTimeoutMs(process.env),\n            workerInfo.pane_id,\n            workerInfo.pid,\n            config.tmux_pane_owner_id ?? undefined,\n            config.hud_pane_id ?? undefined,\n          );\n        } else {\n          await new Promise<void>(r => setTimeout(r, assignRetryDelayS * 1000));\n        }\n      }\n    }\n    if (!outcome.ok) {\n      throw new Error('worker_notify_failed');\n    }\n  } catch (error) {\n    // Roll back claim to avoid stuck in_progress tasks on any post-claim dispatch failure.\n    const released = await releaseTaskClaim(sanitized, taskId, claim.claimToken, workerName, cwd);\n\n    const reason = error instanceof Error && error.message.trim() !== ''\n      ? error.message\n      : 'worker_assignment_failed';\n\n    try {\n      await writeWorkerInbox(\n        sanitized,\n        workerName,\n        `# Assignment Cancelled\\n\\nTask ${taskId} was not dispatched due to ${reason}.\\nDo not execute this task from prior inbox content.`,\n        cwd,\n      );\n    } catch (err) {\n      process.stderr.write(`[team/runtime] operation failed: ${err}\\n`);","sourceCodeStart":4769,"sourceCodeEnd":4805,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/runtime.ts#L4769-L4805","documentation":"Thrown after the post-claim worker notification loop when the final dispatch outcome is not ok. The task was successfully claimed but the worker (e.g. its tmux pane/agent session) could not be notified to start work; the surrounding catch then releases the claim.","triggerScenarios":"claimTask succeeds but every dispatch retry (up to 2, including retry delays for trust prompts) fails — e.g. worker pane is dead, tmux send-keys fails, or the agent session is unresponsive.","commonSituations":"Worker pane crashed or was killed between team start and assignment; tmux session/pane IDs stale after a server restart; trust prompt not accepted so dispatch retries exhaust.","solutions":["Verify the worker pane/process is alive (isWorkerAlive / tmux list-panes) before assigning","If the pane is dead, restart or rescale the worker, then re-assign (the claim is auto-released)","Accept pending trust prompts for the worker session so dispatch can succeed"],"exampleFix":"// before\nawait assignTask(team, taskId, worker, cwd);\n\n// after\nif (!isWorkerAlive(config.tmux_session, w.index, w.pane_id, w.pid)) {\n  await rescaleWorker(team, worker); // recreate dead pane\n}\nawait assignTask(team, taskId, worker, cwd);","handlingStrategy":"retry","validationCode":"const alive = isWorkerAlive(config.tmux_session, w.index, w.pane_id, w.pid, config.tmux_pane_owner_id, config.hud_pane_id);\nif (!alive) throw new Error('worker pane dead; restart before dispatch');","typeGuard":"function workerReachable(cfg: TeamConfig, w: WorkerInfo): boolean {\n  return cfg.worker_launch_mode === 'prompt' ? isPromptWorkerAlive(cfg, w) : isWorkerAlive(cfg.tmux_session, w.index, w.pane_id, w.pid);\n}","tryCatchPattern":"try { await assignTask(t, id, w, cwd); } catch (e) { if ((e as Error).message === 'worker_notify_failed') { await restartWorker(t, w); await assignTask(t, id, w, cwd); } else throw e; }","preventionTips":["Health-check worker panes before dispatch","Accept trust prompts when provisioning workers","Auto-restart dead workers and re-dispatch (claim is released for you)"],"tags":["worker","dispatch","tmux"],"backgroundTag":"remote-dispatch-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}