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

Refusing to overwrite existing ${ULTRAGOAL_DIR}/${ULTRAGOAL_

Error message

Refusing to overwrite existing ${ULTRAGOAL_DIR}/${ULTRAGOAL_GOALS}; pass --force to recreate it.

What it means

createUltragoalPlan refuses to silently replace an existing ultragoal plan artifact. Without options.force, an existing goals file is treated as user-owned state and the mutation-lock-guarded create aborts.

Source

Thrown at src/ultragoal/artifacts.ts:1066

  if (!requiresAggregateObjectiveMigration(parsed, ultragoalStatePathPrefix(cwd))) return parsed;
  // The legacy objective migration is a durable story transition: it requires
  // writable lifecycle authority and the mutation lock, and re-reads the plan
  // under the lock so a concurrent mutator cannot be clobbered or duplicated.
  return withUltragoalMutationLock(cwd, async () => readUltragoalPlanUnderLock(cwd));
}

async function writePlan(cwd: string, plan: UltragoalPlan): Promise<void> {
  await mkdir(ultragoalDir(cwd), { recursive: true });
  const path = ultragoalGoalsPath(cwd);
  const tmpPath = `${path}.${process.pid}.${Date.now()}.tmp`;
  await writeFile(tmpPath, `${JSON.stringify(plan, null, 2)}\n`);
  await rename(tmpPath, path);
}

export async function createUltragoalPlan(cwd: string, options: CreateUltragoalOptions): Promise<UltragoalPlan> {
  return withUltragoalMutationLock(cwd, async () => {
  if (!options.force && existsSync(ultragoalGoalsPath(cwd))) {
    throw new UltragoalError(`Refusing to overwrite existing ${ULTRAGOAL_DIR}/${ULTRAGOAL_GOALS}; pass --force to recreate it.`);
  }
  const now = iso(options.now);
  const sourceGoals: Array<{ title?: string; objective: string; tokenBudget?: number }> = options.goals?.length
    ? options.goals
    : deriveGoalCandidates(options.brief);
  const candidates = sourceGoals
    .map((goal, index): UltragoalItem => ({
      id: normalizeGoalId(goal.title ?? titleFromObjective(goal.objective, `Goal ${index + 1}`), index),
      title: goal.title ?? titleFromObjective(goal.objective, `Goal ${index + 1}`),
      objective: goal.objective.trim(),
      status: 'pending',
      tokenBudget: goal.tokenBudget,
      attempt: 0,
      createdAt: now,
      updatedAt: now,
    }));

  const plan: UltragoalPlan = {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Pass --force (options.force = true) if you intentionally want to recreate the plan
  2. If the existing plan is wanted, skip the create step (make the pipeline idempotent: check existence first)
  3. Delete or move the existing artifact only if you are sure it's disposable
  4. Audit CI scripts for unconditional create-goals invocations

Example fix

// before
await createUltragoalPlan(cwd, { brief }); // throws if plan exists

// after
await createUltragoalPlan(cwd, { brief, force: true });
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
if (!existsSync(ultragoalGoalsPath(cwd))) { await createUltragoalPlan(cwd, { brief }); }

Try / catch

try { await createUltragoalPlan(cwd, { brief }); } catch (e) { if (e instanceof UltragoalError && e.message.includes('pass --force')) { /* plan already exists; decide explicitly */ } else throw e; }

Prevention

When it happens

Trigger: Calling createUltragoalPlan(cwd, {force: false, ...}) (the default) when .ultragoal/<ULTRAGOAL_GOALS> already exists — e.g. re-running `omx ultragoal create-goals` twice, or in CI where a previous step already created the plan.

Common situations: Re-running a setup script or pipeline stage that calls create-goals without an idempotency check; CI caching that leaves a stale plan in the workspace; two agents/processes racing to initialize a repo's plan.

Related errors


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