Yeachan-Heo/oh-my-codex · error · UltragoalError
Missing --evidence.
Error message
Missing --evidence.
What it means
Every structured steering proposal must carry non-empty evidence (why the mutation is justified) — enforced after parseSteeringProposal in the steer command. Both --evidence as a flag and evidence inside --after-json/--directive-json count; the guard uses evidence?.trim?.() so proposals lacking the field entirely also fail.
Source
Thrown at src/cli/ultragoal.ts:461
console.log(`ultragoal added goal: ${result.goal.id}`);
printStatus(result.plan);
}
return;
}
if (command === 'steer') {
const proposalText = readValue(rest, '--proposal');
const source = readValue(rest, '--source');
if (proposalText) {
const parsed = assertPlainObject(await readJsonInput(proposalText, '--proposal'), '--proposal');
const proposal = normalizeSteeringProposal({ ...parsed, source: source ?? parsed.source }, proposalText);
const result = await steerUltragoal(cwd, proposal, { directiveText: proposalText });
printSteerResult(proposal, result, json);
if (!result.accepted) process.exitCode = 1;
return;
}
const proposal = await parseSteeringProposal(rest);
if (!proposal.evidence?.trim?.()) throw new UltragoalError('Missing --evidence.');
if (!proposal.rationale?.trim?.()) throw new UltragoalError('Missing --rationale.');
proposal.source = parseSteeringSource(source, proposal.source);
const result = await steerUltragoal(cwd, proposal, { directiveText: buildSteerDirectiveText(rest) });
printSteerResult(proposal, result, json);
if (!result.accepted) process.exitCode = 1;
return;
}
if (command === 'record-review-blockers') {
const goalId = readValue(rest, '--goal-id');
const title = readValue(rest, '--title');
const objective = readValue(rest, '--objective');
const evidence = readValue(rest, '--evidence');
if (!goalId) throw new UltragoalError('Missing --goal-id.');
if (!title?.trim()) throw new UltragoalError('Missing --title.');
if (!objective?.trim()) throw new UltragoalError('Missing --objective.');
if (!evidence?.trim()) throw new UltragoalError('Missing --evidence.');
const codexGoal = await parseCodexGoalJson(readValue(rest, '--codex-goal-json'));View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Add `--evidence "..."` citing concrete artifacts (test run, log, review link)
- If using --after-json/--directive-json, include a non-empty "evidence" string in the object
Example fix
# before omx ultragoal steer --kind update_goal --goal-id g1 --status paused --rationale 'flaky' # Error: Missing --evidence. # after omx ultragoal steer --kind update_goal --goal-id g1 --status paused --evidence 'ci run 1234 red' --rationale 'flaky'
Defensive patterns
Strategy: validation
Validate before calling
if (!evidence?.trim()) { console.error('steer requires non-empty --evidence'); process.exit(2); } Type guard
function hasEvidence(p: { evidence?: string }): boolean {
return typeof p.evidence === 'string' && p.evidence.trim().length > 0;
} Prevention
- Always pair evidence (facts) with rationale (reasoning) in steering proposals
- Include 'evidence' key in generated --after-json objects
When it happens
Trigger: `omx ultragoal steer --kind update_goal ...` with no --evidence and no evidence key in the JSON proposal; or evidence being only whitespace.
Common situations: Treating evidence as optional metadata; proposal JSON built programmatically that omits evidence; merging older proposal templates without the field.
Related errors
- Missing --kind for structured ultragoal steer.
- Missing --rationale.
- omx ultragoal steer rejects broad natural-language mutation
- Missing brief text. Pass --brief, --brief-file, --from-stdin
- Missing --title.
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/a914940f89116214.
Report an issue: GitHub.