{"record":{"id":"00a0bb8f50dbf9ee","repo":"Yeachan-Heo/oh-my-codex","slug":"omx-ultragoal-steer-rejects-broad-natural-language","errorCode":null,"errorMessage":"omx ultragoal steer rejects broad natural-language mutation requests; pass structured fields or --directive-json.","messagePattern":"omx ultragoal steer rejects broad natural-language mutation requests; pass structured fields or --directive-json\\.","errorType":"exception","errorClass":"UltragoalError","httpStatus":null,"severity":"error","filePath":"src/cli/ultragoal.ts","lineNumber":274,"sourceCode":"    targetGoalId: normalizeTargetGoalId(raw),\n    title: typeof raw.title === 'string' ? raw.title : undefined,\n    objective: typeof raw.objective === 'string' ? raw.objective : undefined,\n    after,\n    pendingOrder: Array.isArray(raw.pendingOrder) ? raw.pendingOrder.filter((id): id is string => typeof id === 'string') : undefined,\n    idempotencyKey: typeof raw.idempotencyKey === 'string' ? raw.idempotencyKey : undefined,\n  };\n}\n\nasync function parseSteeringProposal(args: readonly string[]): Promise<UltragoalSteeringProposal> {\n  const directiveFile = readValue(args, '--directive-file');\n  const directiveRaw = readValue(args, '--directive-json') ?? (directiveFile ? await readFile(directiveFile, 'utf-8') : undefined);\n  if (directiveRaw) {\n    const directive = assertPlainObject(await readJsonInput(directiveRaw, '--directive-json'), '--directive-json');\n    return normalizeSteeringProposal(directive, directiveRaw.trim().startsWith('{') ? directiveRaw : undefined);\n  }\n\n  const freeform = positionalText(args);\n  if (freeform) throw new UltragoalError('omx ultragoal steer rejects broad natural-language mutation requests; pass structured fields or --directive-json.');\n\n  const after = await readJsonInput(readValue(args, '--after-json'), '--after-json');\n  return normalizeSteeringProposal({\n    kind: readValue(args, '--kind'),\n    evidence: readValue(args, '--evidence'),\n    rationale: readValue(args, '--rationale'),\n    targetGoalId: readValue(args, '--target-goal-id') ?? readValue(args, '--goal-id'),\n    title: readValue(args, '--title'),\n    objective: readValue(args, '--objective'),\n    after,\n    idempotencyKey: readValue(args, '--idempotency-key'),\n  });\n}\n\nfunction buildSteerDirectiveText(args: readonly string[]): string {\n  return args.join(' ');\n}\n","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/ultragoal.ts#L256-L292","documentation":"ultragoal steer deliberately refuses freeform natural-language positional text as a mutation request. Because mutations are leader-owned and auditable, the CLI only accepts structured fields (--kind/--evidence/--rationale/etc.), an --after-json proposal, or a full --directive-json document.","triggerScenarios":"Running `omx ultragoal steer \"please pause all goals\"` — i.e. supplying positional freeform text without --directive-json; the code detects positionalText(args) and throws.","commonSituations":"Habit from other AI CLIs that accept prose commands; older workflows before structured steering was enforced; scripts written against a previous freeform interface.","solutions":["Convert the intent into structured flags: --kind, --evidence, --rationale plus kind-specific fields","Use --after-json with a proposal object","Use --directive-json with a complete directive document for complex multi-field mutations"],"exampleFix":"# before\nomx ultragoal steer \"pause the api goal\"\n# Error: omx ultragoal steer rejects broad natural-language mutation requests...\n\n# after\nomx ultragoal steer --kind update_goal --goal-id api-1 --status paused --evidence 'flaky ci' --rationale 'pause until green'","handlingStrategy":"validation","validationCode":"const args = ['pause the api goal']; // freeform\nif (args.length && !hasDirectiveJson) {\n  // convert intent to structured flags instead of passing prose\n  throw new Error('convert freeform text to --kind/--evidence/--rationale or --directive-json');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass prose to steer; author mutations as structured flags or JSON","Keep a snippet library of well-formed steer commands"],"tags":["cli","ultragoal","api-contract","steering"],"backgroundTag":"structured-input-required","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}