Yeachan-Heo/oh-my-codex · error · UltragoalError
Blocked ultragoal checkpoint Codex snapshot is missing objec
Error message
Blocked ultragoal checkpoint Codex snapshot is missing objective text.
What it means
The Codex snapshot supplied for a blocked checkpoint is available but contains no objective text. Objective matching is mandatory for blocked checkpoints, so an empty objective cannot be reconciled against the plan's expected/compatible objectives.
Source
Thrown at src/ultragoal/artifacts.ts:1819
plan.activeGoalId = goal.id;
plan.updatedAt = now;
await writePlan(cwd, plan);
await appendLedger(cwd, {
ts: now,
event: 'goal_blocked',
goalId: goal.id,
status: goal.status,
evidence: options.evidence,
codexGoal: options.codexGoal,
message: 'Codex get_goal was unavailable due to a DB/schema/context error; strict completion reconciliation is deferred until get_goal works.',
});
return plan;
}
if (!snapshot?.available) {
throw new UltragoalError('Blocked ultragoal checkpoints require either a get_goal snapshot for the completed legacy Codex goal that blocked create_goal, an unavailable get_goal error JSON for a Codex DB/schema/context failure, or a matching native blocked snapshot; pass --codex-goal-json.');
}
if (!snapshot.objective) {
throw new UltragoalError('Blocked ultragoal checkpoint Codex snapshot is missing objective text.');
}
const blockedSnapshotMatchesExpected = [expectedCodexObjective(plan, goal), ...compatibleCodexObjectives(plan)]
.some((objective) => normalizeObjective(objective) === normalizeObjective(snapshot.objective ?? ''));
if (snapshot.status === 'blocked') {
if (!blockedSnapshotMatchesExpected) {
throw new UltragoalError(
`Blocked ultragoal checkpoint objective mismatch: expected one of [${[expectedCodexObjective(plan, goal), ...compatibleCodexObjectives(plan)].join(' | ')}], got ${snapshot.objective}. Matching native blocked checkpoints require the expected/compatible Codex objective; finish or clear the foreign goal, or pass a matching blocked get_goal snapshot with --evidence.`,
);
}
const evidence = assertNonEmpty(options.evidence, '--evidence');
goal.updatedAt = now;
plan.activeGoalId = goal.id;
plan.updatedAt = now;
await writePlan(cwd, plan);
await appendLedger(cwd, {
ts: now,
event: 'goal_blocked',
goalId: goal.id,View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Re-fetch the goal with get_goal and confirm the objective field is populated before recording the checkpoint
- If the upstream goal genuinely has no objective, that goal cannot be used as blocked-checkpoint evidence — fix the goal definition or use the db_schema_context_error deferral path
- Update snapshot fixtures to include objective text
Defensive patterns
Strategy: validation
Validate before calling
const snap = parseCodexGoalSnapshot(options.codexGoal);
if (snap?.available && !snap.objective) throw new Error('snapshot missing objective'); Type guard
const snapshotHasObjective = (s: any): s is { objective: string } => typeof s?.objective === 'string' && s.objective.length > 0; Prevention
- Assert objective presence on every fetched snapshot
- Keep snapshot fixtures in sync with the get_goal schema
When it happens
Trigger: Passing --codex-goal-json whose parsed snapshot has available: true but objective is empty/undefined.
Common situations: get_goal returning a sparse object; hand-written snapshot fixtures that omit the objective field; API version changes dropping the objective field.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- formatCodexGoalReconciliation(reconciliation)
- Native hook transaction wrote invalid hooks.json: ${validati
- Missing notification metadata snapshot for ${notifyPlan.meta
- Missing notification metadata snapshot for ${metadataPath};
- Unsafe Autopilot context snapshot path: ${existingSnapshot.p
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/0dc16e3db4d46fbd.
Report an issue: GitHub.