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

Unknown ultragoal id: ${options.goalId}

Error message

Unknown ultragoal id: ${options.goalId}

What it means

checkpointUltragoal could not find any goal in the plan whose id equals options.goalId. Every checkpoint mutation must target an existing goal id in the ultragoal plan for this repo.

Source

Thrown at src/ultragoal/artifacts.ts:1788

  next.attempt += 1;
  next.startedAt = now;
  next.failedAt = undefined;
  next.failureReason = undefined;
  clearGoalBlockerFields(next);
  next.updatedAt = now;
  plan.activeGoalId = next.id;
  plan.updatedAt = now;
  await writePlan(cwd, plan);
  await appendLedger(cwd, { ts: now, event: 'goal_started', goalId: next.id, status: next.status, message: `Attempt ${next.attempt}` });
  return { plan, goal: next, resumed: false, done: false };
  });
}

export async function checkpointUltragoal(cwd: string, options: CheckpointOptions): Promise<UltragoalPlan> {
  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}`);
  if (plan.aggregateCompletion?.status === 'complete' && options.status !== 'complete') {
    throw new UltragoalError(`Cannot record a ${options.status} checkpoint for ${goal.id} after the aggregate ultragoal plan is complete; the terminal aggregate receipt is immutable.`);
  }
  const now = iso(options.now);
  if (options.status === 'blocked') {
    if (goal.status !== 'in_progress') {
      throw new UltragoalError(`Cannot record a blocked checkpoint for ${goal.id} while it is ${goal.status}; start or resume the ultragoal before recording a non-terminal blocker.`);
    }
    const snapshot = options.codexGoal === undefined ? null : parseCodexGoalSnapshot(options.codexGoal);
    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',

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. List the plan goals (read the ultragoal plan artifact) and use the exact id string
  2. If the plan was recreated, update your script/config to the new goal ids
  3. Ensure you run the checkpoint in the repo whose plan contains the goal

Example fix

// before
await checkpointUltragoal(cwd, { goalId: 'goal-42', status: 'in_progress' });
// after
const plan = await readUltragoalPlan(cwd);
const goal = plan.goals.find(g => g.title.includes('migrate'))!;
await checkpointUltragoal(cwd, { goalId: goal.id, status: 'in_progress' });
Defensive patterns

Strategy: type-guard

Validate before calling

const plan = await readUltragoalPlan(cwd);
if (!plan.goals.some(g => g.id === options.goalId)) throw new Error(`goalId ${options.goalId} not in plan`);

Type guard

const goalExists = (plan: UltragoalPlan, id: string) => plan.goals.some(g => g.id === id);

Try / catch

catch (e) { if (e instanceof UltragoalError && /Unknown ultragoal id/.test(e.message)) { await refreshPlanAndRetry(); } else throw e; }

Prevention

When it happens

Trigger: Calling checkpointUltragoal with a goalId that is not in plan.goals — typo'd id, stale id from a previous plan, or an id belonging to a different repo's plan.

Common situations: Scripts hard-coding goal ids after the plan was recreated; referencing a goal id from an earlier session or from the plan file before it was rewritten; copy-paste of ids between repositories.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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