Yeachan-Heo/oh-my-codex · error · UltragoalError
Cannot record final review blockers for ${goal.id} while it
Error message
Cannot record final review blockers for ${goal.id} while it is ${goal.status}; start or resume the ultragoal first. What it means
recordFinalReviewBlockers requires the target goal to be in_progress. You cannot record final review blockers for a goal that is pending, complete, failed, or review_blocked — start or resume it first.
Source
Thrown at src/ultragoal/artifacts.ts:2090
status: goal.status,
evidence: options.evidence,
codexGoal: options.codexGoal,
qualityGate,
message: 'Aggregate ultragoal plan completed with a clean final quality gate.',
});
}
return plan;
});
}
export async function recordFinalReviewBlockers(cwd: string, options: RecordFinalReviewBlockersOptions): Promise<{ plan: UltragoalPlan; blockedGoal: UltragoalItem; addedGoal: UltragoalItem }> {
return withUltragoalMutationLock(cwd, async () => {
const plan = await readUltragoalPlanUnderLock(cwd);
const goal = plan.goals.find((candidate) => candidate.id === options.goalId);
if (!goal) throw new UltragoalError(`Unknown ultragoal id: ${options.goalId}`);
assertNonEmpty(options.evidence, '--evidence');
if (goal.status !== 'in_progress') {
throw new UltragoalError(`Cannot record final review blockers for ${goal.id} while it is ${goal.status}; start or resume the ultragoal first.`);
}
if (!isFinalRunCompletionCandidate(plan, goal)) {
throw new UltragoalError(`Cannot record final review blockers for ${goal.id}; it is not the only unresolved ultragoal story.`);
}
const now = iso(options.now);
const expectedObjective = expectedCodexObjective(plan, goal);
const aggregateMode = codexGoalMode(plan) === 'aggregate';
const reconciliation = reconcileCodexGoalSnapshot(
options.codexGoal === undefined ? null : parseCodexGoalSnapshot(options.codexGoal),
{
expectedObjective,
acceptedObjectives: aggregateMode ? compatibleCodexObjectives(plan) : undefined,
allowedStatuses: ['active'],
requireSnapshot: true,
requireComplete: false,
},
);View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Record an in_progress checkpoint for the goal first, then call recordFinalReviewBlockers
- Guard against duplicate invocations in your orchestration
- If the goal is already review_blocked, no further blocker recording is needed for it
Defensive patterns
Strategy: validation
Validate before calling
if (goal.status !== 'in_progress') await checkpointUltragoal(cwd, { goalId, status: 'in_progress', evidence: 'start' }); Type guard
const isInProgress = (goal: UltragoalItem) => goal.status === 'in_progress';
Prevention
- Start the goal before recording blockers
- Idempotency-check before re-invoking blocker recording
When it happens
Trigger: Calling recordFinalReviewBlockers when goal.status !== 'in_progress' (e.g. 'pending' never started, or already 'review_blocked').
Common situations: Calling the blocker-recording step before the start checkpoint; double-invoking the same blocker recording; retrying after the goal transitioned away.
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
- Cannot record a blocked checkpoint for ${goal.id} while it i
- Cannot record a blocked ultragoal checkpoint while the exist
- Cannot record final review blockers for ${goal.id}; it is no
- formatCodexGoalReconciliation(reconciliation)
- preLaunch ${completion.operation} failed
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/9407341276c17fb4.
Report an issue: GitHub.