{"record":{"id":"5f1577d2ae4538e4","repo":"Yeachan-Heo/oh-my-codex","slug":"refusing-to-overwrite-existing-ultragoal-dir","errorCode":null,"errorMessage":"Refusing to overwrite existing ${ULTRAGOAL_DIR}/${ULTRAGOAL_GOALS}; pass --force to recreate it.","messagePattern":"Refusing to overwrite existing (.+?)/(.+?); pass --force to recreate it\\.","errorType":"exception","errorClass":"UltragoalError","httpStatus":null,"severity":"warning","filePath":"src/ultragoal/artifacts.ts","lineNumber":1066,"sourceCode":"  if (!requiresAggregateObjectiveMigration(parsed, ultragoalStatePathPrefix(cwd))) return parsed;\n  // The legacy objective migration is a durable story transition: it requires\n  // writable lifecycle authority and the mutation lock, and re-reads the plan\n  // under the lock so a concurrent mutator cannot be clobbered or duplicated.\n  return withUltragoalMutationLock(cwd, async () => readUltragoalPlanUnderLock(cwd));\n}\n\nasync function writePlan(cwd: string, plan: UltragoalPlan): Promise<void> {\n  await mkdir(ultragoalDir(cwd), { recursive: true });\n  const path = ultragoalGoalsPath(cwd);\n  const tmpPath = `${path}.${process.pid}.${Date.now()}.tmp`;\n  await writeFile(tmpPath, `${JSON.stringify(plan, null, 2)}\\n`);\n  await rename(tmpPath, path);\n}\n\nexport async function createUltragoalPlan(cwd: string, options: CreateUltragoalOptions): Promise<UltragoalPlan> {\n  return withUltragoalMutationLock(cwd, async () => {\n  if (!options.force && existsSync(ultragoalGoalsPath(cwd))) {\n    throw new UltragoalError(`Refusing to overwrite existing ${ULTRAGOAL_DIR}/${ULTRAGOAL_GOALS}; pass --force to recreate it.`);\n  }\n  const now = iso(options.now);\n  const sourceGoals: Array<{ title?: string; objective: string; tokenBudget?: number }> = options.goals?.length\n    ? options.goals\n    : deriveGoalCandidates(options.brief);\n  const candidates = sourceGoals\n    .map((goal, index): UltragoalItem => ({\n      id: normalizeGoalId(goal.title ?? titleFromObjective(goal.objective, `Goal ${index + 1}`), index),\n      title: goal.title ?? titleFromObjective(goal.objective, `Goal ${index + 1}`),\n      objective: goal.objective.trim(),\n      status: 'pending',\n      tokenBudget: goal.tokenBudget,\n      attempt: 0,\n      createdAt: now,\n      updatedAt: now,\n    }));\n\n  const plan: UltragoalPlan = {","sourceCodeStart":1048,"sourceCodeEnd":1084,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/ultragoal/artifacts.ts#L1048-L1084","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass --force (options.force = true) if you intentionally want to recreate the plan","If the existing plan is wanted, skip the create step (make the pipeline idempotent: check existence first)","Delete or move the existing artifact only if you are sure it's disposable","Audit CI scripts for unconditional create-goals invocations"],"exampleFix":"// before\nawait createUltragoalPlan(cwd, { brief }); // throws if plan exists\n\n// after\nawait createUltragoalPlan(cwd, { brief, force: true });","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nif (!existsSync(ultragoalGoalsPath(cwd))) { await createUltragoalPlan(cwd, { brief }); }","typeGuard":null,"tryCatchPattern":"try { await createUltragoalPlan(cwd, { brief }); } catch (e) { if (e instanceof UltragoalError && e.message.includes('pass --force')) { /* plan already exists; decide explicitly */ } else throw e; }","preventionTips":["Make create-goals steps idempotent: check existence before creating","Only pass force when you accept losing the existing plan","In CI, clean or cache the workspace deliberately so plan state is predictable"],"tags":["ultragoal","refuse-overwrite","safety-guard","idempotency"],"backgroundTag":"refuse-to-overwrite-existing-resource","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}