Yeachan-Heo/oh-my-codex · error · Error
claim.error
Error message
claim.error
What it means
Generic passthrough of a failed task claim: claimTask returned ok:false with an error other than 'blocked_dependency', and that raw error string is rethrown verbatim. Typical values include version conflicts (task.version mismatch) or already-claimed states.
Source
Thrown at src/team/runtime.ts:4714
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`);
const workerInfo = config.workers.find(w => w.name === workerName);
if (!workerInfo) throw new Error(`Worker ${workerName} not found in team`);
const dispatchPolicy = resolveDispatchPolicy(manifest?.policy, config.worker_launch_mode);
const claim = await claimTask(sanitized, taskId, workerName, task.version ?? 1, cwd);
if (!claim.ok) {
if (claim.error === 'blocked_dependency') {
throw new Error(`blocked_dependency:${(claim.dependencies ?? []).join(',')}`);
}
throw new Error(claim.error);
}
try {
// Retry dispatch up to 2 times to handle trust prompts during assignment (fixes #393).
const approvedExecutionState = await resolvePersistedApprovedTeamExecutionContinuityState(
sanitized,
config.leader_cwd ?? cwd,
config.team_state_root ?? resolveCanonicalTeamStateRoot(config.leader_cwd ?? cwd),
);
const persistedUltragoalContext = await readPersistedTeamUltragoalContext(
sanitized,
config.leader_cwd ?? cwd,
config.team_state_root ?? resolveCanonicalTeamStateRoot(config.leader_cwd ?? cwd),
);
const approvedContextSection = joinContextSections(
approvedExecutionState.status === 'valid'
? buildApprovedTeamHandoffSection(approvedExecutionState.approvedHint)
: undefined,View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Re-read the task to get its current version and check its status before re-claiming
- Serialize assignment of a given task (only one dispatcher) to avoid claim races
- Inspect the specific claim.error string to identify the exact claim failure mode
Example fix
// before
await assignTask(team, taskId, worker, cwd); // uses task.version ?? 1
// after
const fresh = await readTask(team, taskId, cwd);
if (!fresh || fresh.status !== 'pending') throw new Error('task no longer claimable');
await claimTask(team, taskId, worker, fresh.version ?? 1, cwd); Defensive patterns
Strategy: retry
Validate before calling
const fresh = await readTask(teamName, taskId, cwd);
if (fresh?.status !== 'pending') throw new Error('not claimable'); Try / catch
try { await assignTask(t, id, w, cwd); } catch (e) { if (/version|claimed/.test((e as Error).message)) { await sleep(500); await assignTask(t, id, w, cwd); } else throw e; } Prevention
- Re-read task version immediately before claiming
- Single dispatcher per task to avoid races
- Treat raw claim.error strings as authoritative failure modes
When it happens
Trigger: Concurrent assignment where another worker claimed the task first (claim token/version mismatch), or the supplied task.version ?? 1 is stale relative to the stored task record.
Common situations: Two dispatchers racing on the same task; retrying assignment with a cached stale task object (old version); task mutated between read and claim.
Related errors
- autoresearch_active_run_exists
- timed out waiting for tmux extended-keys lease lock: ${lockP
- [native-assets] publication-lock-timeout: ${path}; elapsed=$
- Native hook transaction rollback preserved ${artifact.path}
- exec_followup_queue_lock_timeout
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/5eb19ce2b0a74876.
Report an issue: GitHub.