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

No ultragoal plan found at ${repoRelative(cwd, path)}. Run `

Error message

No ultragoal plan found at ${repoRelative(cwd, path)}. Run `omx ultragoal create-goals ...` first.

What it means

The ultragoal plan file (.ultragoal goals artifact) could not be read from disk. This library stores the ultragoal plan as a JSON artifact in the repo, and any command that needs an existing plan (add goal, steer, finalize, etc.) first reads it; if readFile fails (missing file, unreadable path, wrong cwd), this error is thrown.

Source

Thrown at src/ultragoal/artifacts.ts:988

    await handle.close().catch(() => undefined);
    await rm(lockPath, { force: true }).catch(() => undefined);
  }
}

async function appendLedger(cwd: string, entry: UltragoalLedgerEntry): Promise<void> {
  await mkdir(ultragoalDir(cwd), { recursive: true });
  const path = ultragoalLedgerPath(cwd);
  await appendFile(path, `${JSON.stringify(entry)}\n`);
}

/** Pure plan read: no durable writes, no migration. */
async function readUltragoalPlanFile(cwd: string): Promise<UltragoalPlan> {
  const path = ultragoalGoalsPath(cwd);
  let raw: string;
  try {
    raw = await readFile(path, 'utf-8');
  } catch {
    throw new UltragoalError(`No ultragoal plan found at ${repoRelative(cwd, path)}. Run \`omx ultragoal create-goals ...\` first.`);
  }
  const parsed = JSON.parse(raw) as UltragoalPlan;
  if (parsed.version !== 1 || !Array.isArray(parsed.goals)) {
    throw new UltragoalError(`Invalid ultragoal plan at ${repoRelative(cwd, path)}.`);
  }
  return parsed;
}

/**
 * Pure, lock-free plan read for read-only surfaces such as
 * `omx ultragoal status`: never migrates, never writes, and is therefore safe
 * for Team workers. Durable legacy migration only happens through
 * readUltragoalPlan or the mutators, under the mutation lock and authority gate.
 */
export async function readUltragoalPlanSnapshot(cwd: string): Promise<UltragoalPlan> {
  return readUltragoalPlanFile(cwd);
}

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Run `omx ultragoal create-goals ...` in the repo root to create the plan
  2. Verify you are running from the same repo/cwd the plan was created in (check the path in the error message)
  3. Check whether the plan file exists at the reported path (ls .ultragoal) and restore it from git history if it was deleted
  4. If running in CI, ensure the step that generates/commits the ultragoal plan runs before plan-dependent steps

Example fix

# before
omx ultragoal add-goal --objective "ship it"   # throws 1170

# after
omx ultragoal create-goals --brief "..."       # creates the plan first
omx ultragoal add-goal --objective "ship it"
Defensive patterns

Strategy: validation

Validate before calling

import { pathExists } from 'fs-extra';
// or: import { existsSync } from 'node:fs';
const hasPlan = await pathExists(ultragoalGoalsPath(cwd));
if (!hasPlan) await createUltragoalPlan(cwd, { brief });

Try / catch

try { await addUltragoalGoal(cwd, opts); } catch (e) { if (e instanceof UltragoalError && /No ultragoal plan found/.test(e.message)) { await createUltragoalPlan(cwd, { brief }); } else throw e; }

Prevention

When it happens

Trigger: Calling any ultragoal API/command that assumes an existing plan (e.g. addUltragoalGoal, steering, finalize) in a repo/cwd where `omx ultragoal create-goals ...` was never run, or where the ULTRAGOAL_DIR artifact was deleted or the cwd is not the repo root the plan was created in.

Common situations: Fresh clone or CI checkout without the committed .ultragoal artifact; running the CLI from a subdirectory so the relative plan path doesn't resolve; accidentally .gitignore-ing or deleting the plan file; running in a temp/worktree directory.

Related errors


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