Yeachan-Heo/oh-my-codex · error · Error
teamContinuationRequiredDiagnostic(phaseState)
Error message
teamContinuationRequiredDiagnostic(phaseState)
What it means
Thrown when a team task operation is attempted on a team whose phase state is terminal (a terminal_epoch is recorded or the current_phase is a terminal phase). The runtime refuses to continue normal task workflows after the team has finished/shut down, and instead emits a diagnostic describing the terminal state.
Source
Thrown at src/team/runtime.ts:4686
updated_at: updatedAt,
},
};
}
/**
* Assign a task to a worker by writing inbox and sending trigger.
*/
export async function assignTask(
teamName: string,
workerName: string,
taskId: string,
cwd: string,
): Promise<void> {
const sanitized = sanitizeTeamName(teamName);
return await withTeamTaskMembershipBarrier(sanitized, cwd, async () => {
const phaseState = await readTeamPhaseState(sanitized, cwd);
if (phaseState?.terminal_epoch || (phaseState && isTerminalPhase(phaseState.current_phase))) {
throw new Error(teamContinuationRequiredDiagnostic(phaseState));
}
const task = await readTask(sanitized, taskId, cwd);
if (!task) throw new Error(`Task ${taskId} not found`);
const manifest = await readTeamManifestV2(sanitized, cwd);
const governance = resolveGovernancePolicy(manifest?.governance);
if (governance.delegation_only && workerName === 'leader-fixed') {
throw new Error('delegation_only_violation');
}
if (governance.plan_approval_required && task.requires_code_change === true) {
const approved = await isTaskApprovedForExecution(sanitized, taskId, cwd);
if (!approved) {
throw new Error('plan_approval_required');
}
}
const config = await readTeamConfig(sanitized, cwd);
if (!config) throw new Error(`Team ${sanitized} not found`);View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Check the team phase state (readTeamPhaseState) or team status before dispatching tasks; if terminal, restart or recreate the team
- If the team should still be alive, inspect the phase-state file for a prematurely written terminal_epoch or terminal phase and reconcile it
- Wrap dispatch calls in try-catch and surface the diagnostic message to the operator instead of retrying blindly
Example fix
// before
await assignTask(teamName, taskId, workerName, cwd);
// after
const phase = await readTeamPhaseState(teamName, cwd);
if (phase?.terminal_epoch || isTerminalPhase(phase?.current_phase ?? '')) {
throw new Error('team already terminal; recreate it before assigning tasks');
}
await assignTask(teamName, taskId, workerName, cwd); Defensive patterns
Strategy: validation
Validate before calling
const phase = await readTeamPhaseState(teamName, cwd);
if (phase?.terminal_epoch || isTerminalPhase(phase?.current_phase ?? '')) {
throw new Error('team is terminal; recreate it before assigning tasks');
} Type guard
function isTeamContinuable(phase: TeamPhaseState | null | undefined): boolean {
return !!phase && !phase.terminal_epoch && !isTerminalPhase(phase.current_phase);
} Try / catch
try { await assignTask(t, id, w, cwd); } catch (e) { if (String((e as Error).message).includes('terminal')) await recreateTeam(t); else throw e; } Prevention
- Check team phase state before every dispatch
- Alert when a team enters a terminal phase so pipelines stop queuing work
- Do not hard-retry assignment errors on terminal teams
When it happens
Trigger: Calling the task-assignment entry point (the function around src/team/runtime.ts:4686) after the team reached a terminal phase — e.g. after shutdown completed or a terminal_epoch was written to team phase state. The check fires before the task is even read.
Common situations: A queued job/CI pipeline retries task dispatch after a team was shut down mid-run; stale scripts referencing a team that already completed its lifecycle; phase-state file left in a terminal state after a crash during shutdown.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Conflicting setup Team mode flags: ${source} selects ${next}
- Invalid setup Team mode: ${next}. Expected one of: enabled,
- Missing setup Team mode value after --team-mode. Expected on
- detached leader interrupted before release: ${interrupted}
- detached launch aborted before release
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/79919b642061540f.
Report an issue: GitHub.