Yeachan-Heo/oh-my-codex · error · UltragoalError
Invalid ${label}: ${message}
Error message
Invalid ${label}: ${message} What it means
readJsonInput parses values for flags like --directive-json and --after-json. It accepts either inline JSON (value starting with { or [) or a filesystem path to a JSON file. If neither parses — bad JSON syntax or an unreadable/missing file — it throws UltragoalError labeled with the flag name and the underlying parse error message.
Source
Thrown at src/cli/ultragoal.ts:185
`Required external decision: ${blocked.requiredExternalDecision ?? 'provide the missing authorization/credential, or explicitly choose a different unblock path'}.`,
'Do not run complete-goals --retry-failed again until that external state changes or the user explicitly authorizes an unblock path.',
].join('\n');
}
async function parseCodexGoalJson(raw: string | undefined): Promise<unknown> {
if (!raw) return undefined;
return readCodexGoalSnapshotInput(raw, process.cwd());
}
async function readJsonInput(raw: string | undefined, label = '--quality-gate-json'): Promise<unknown> {
if (!raw) return undefined;
try {
const trimmed = raw.trim();
if (trimmed.startsWith('{') || trimmed.startsWith('[')) return JSON.parse(trimmed);
return JSON.parse(await readFile(trimmed, 'utf-8'));
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new UltragoalError(`Invalid ${label}: ${message}`);
}
}
const NATIVE_SUBAGENT_CAPACITY_BLOCKER_FILE = 'native-subagent-capacity-blocker.json';
async function readJsonIfExists<T>(path: string): Promise<T | null> {
try {
return JSON.parse(await readFile(path, 'utf-8')) as T;
} catch {
return null;
}
}
async function resolveCodexGoalNativeSubagentSupport(cwd: string) {
const scope = await resolveRuntimeStateScope(cwd);
const [persistedSupportBlocker, persistedCapacityBlocker] = await Promise.all([
readJsonIfExists<Record<string, unknown>>(join(scope.baseStateDir, NATIVE_SUBAGENT_SUPPORT_BLOCKER_FILE)),
readJsonIfExists<Record<string, unknown>>(join(scope.baseStateDir, NATIVE_SUBAGENT_CAPACITY_BLOCKER_FILE)),View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Validate the JSON with `jq . file.json` (or `echo '...' | jq .`) to find the syntax error, then fix it
- If passing a path, confirm it exists and is readable from the CLI's working directory (use an absolute path)
- For inline JSON prefer single-quoted shell strings to avoid interpolation breaking quotes
Example fix
# before
omx ultragoal steer --after-json '{"kind":"add_goal",}'
# Error: Invalid --after-json: Unexpected token } in JSON at position 18
# after
omx ultragoal steer --after-json '{"kind":"add_goal"}' Defensive patterns
Strategy: validation
Validate before calling
function parseJsonArg(raw: string, label: string): unknown {
const t = raw.trim();
const text = t.startsWith('{') || t.startsWith('[') ? t : readFileSync(t, 'utf-8');
return JSON.parse(text); // throws here first, with clearer context
}
// pre-validate before calling the CLI programmatically:
try { parseJsonArg(afterJson, '--after-json'); } catch { console.error('fix JSON before running omx'); } Try / catch
try { await ultragoalCommand(...) } catch (e) { if (e instanceof UltragoalError && e.message.startsWith('Invalid --')) showJsonDiagnostics(raw); else throw e; } Prevention
- Pipe candidate JSON through `jq .` before passing it
- Use absolute paths for file inputs
- Single-quote inline JSON in shells
When it happens
Trigger: Passing `--after-json '{"kind":"x",}'` (trailing comma), `--directive-json missing.json` (ENOENT), or a path whose contents are not valid JSON; also permission errors reading the file.
Common situations: Hand-writing JSON on the shell with quoting mistakes; relative path resolved against an unexpected cwd; file generated by another tool with BOM or trailing text; single-quote heredoc issues.
Related errors
- Invalid --input JSON: ${error instanceof Error ? error.messa
- ${label} must be a JSON object.
- Unknown adapt argument: ${arg}
- Unknown adapt subcommand: ${subcommand}. Supported subcomman
- agents-init accepts at most one path argument.\n${AGENTS_INI
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/c4d554afbe3b841b.
Report an issue: GitHub.