Yeachan-Heo/oh-my-codex · error · UltragoalError

Blocked ultragoal checkpoints require either a get_goal snap

Error message

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.

What it means

A blocked checkpoint requires a Codex get_goal snapshot proving the blocking condition, but the provided --codex-goal-json is missing, unparseable, or marks the snapshot as unavailable for a reason other than the accepted db_schema_context_error. The strict reconciliation layer refuses to record a native blocked checkpoint without that evidence.

Source

Thrown at src/ultragoal/artifacts.ts:1816

    if (snapshot?.unavailableReason === 'db_schema_context_error') {
      goal.updatedAt = now;
      goal.failureReason = assertNonEmpty(options.evidence, '--evidence');
      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, {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Re-run Codex get_goal and pass its JSON via --codex-goal-json with the snapshot available
  2. If get_goal itself is failing on a Codex DB/schema/context error, pass that error JSON so the checkpoint records the deferred-reconciliation variant
  3. Verify the snapshot parses (parseCodexGoalSnapshot) and has available: true

Example fix

// before
await checkpointUltragoal(cwd, { goalId, status: 'blocked' });
// after
await checkpointUltragoal(cwd, { goalId, status: 'blocked', codexGoal: await codex.getGoalJson(), evidence: 'blocked by upstream migration' });
Defensive patterns

Strategy: validation

Validate before calling

const snap = parseCodexGoalSnapshot(options.codexGoal ?? '');
if (!snap || (!snap.available && snap.unavailableReason !== 'db_schema_context_error')) throw new Error('need a get_goal snapshot via --codex-goal-json');

Type guard

const hasBlockedEvidence = (s: ReturnType<typeof parseCodexGoalSnapshot> | null) =>
  !!s && (s.available || s.unavailableReason === 'db_schema_context_error');

Prevention

When it happens

Trigger: Calling checkpointUltragoal with status 'blocked' where options.codexGoal is undefined, or the parsed snapshot has available !== true and no db_schema_context_error unavailableReason that would defer reconciliation.

Common situations: Forgetting to pass --codex-goal-json; passing malformed get_goal output; passing a get_goal error JSON whose error category is not a DB/schema/context failure so it can't be deferred.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/94750b171f46bbf4. Report an issue: GitHub.