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

--keep-policy must be one of: score_improvement, pass_only

Error message

--keep-policy must be one of: score_improvement, pass_only

What it means

The `--keep-policy` flag for the autoresearch guided-setup init command only accepts two values: `score_improvement` or `pass_only`. The value is normalized (trimmed, lowercased) before validation, so anything that doesn't match those exact strings after normalization throws this error. It exists to prevent silently accepting an unknown keep policy that would later break mission compilation.

Source

Thrown at src/cli/autoresearch-guided.ts:270

}

export function parseInitArgs(
	args: readonly string[],
): Partial<InitAutoresearchOptions> {
	const result: Partial<InitAutoresearchOptions> = {};
	for (let i = 0; i < args.length; i++) {
		const arg = args[i];
		const next = args[i + 1];
		if (arg === "--topic" && next) {
			result.topic = next;
			i++;
		} else if (arg === "--evaluator" && next) {
			result.evaluatorCommand = next;
			i++;
		} else if (arg === "--keep-policy" && next) {
			const normalized = next.trim().toLowerCase();
			if (normalized !== "pass_only" && normalized !== "score_improvement") {
				throw new Error(
					"--keep-policy must be one of: score_improvement, pass_only",
				);
			}
			result.keepPolicy = normalized;
			i++;
		} else if (arg === "--slug" && next) {
			result.slug = slugifyMissionName(next);
			i++;
		} else if (arg.startsWith("--topic=")) {
			result.topic = arg.slice("--topic=".length);
		} else if (arg.startsWith("--evaluator=")) {
			result.evaluatorCommand = arg.slice("--evaluator=".length);
		} else if (arg.startsWith("--keep-policy=")) {
			const normalized = arg
				.slice("--keep-policy=".length)
				.trim()
				.toLowerCase();
			if (normalized !== "pass_only" && normalized !== "score_improvement") {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Use exactly `--keep-policy score_improvement` or `--keep-policy pass_only` (case-insensitive, underscores required).
  2. Check for trailing whitespace or shell quoting that appends characters to the value.
  3. Omit the flag entirely to use the default keep policy.

Example fix

# before
autoresearch init --keep-policy score-improvement

# after
autoresearch init --keep-policy score_improvement
Defensive patterns

Strategy: validation

Validate before calling

const KEEP_POLICIES = new Set(['score_improvement', 'pass_only']);
const v = args['--keep-policy']?.trim().toLowerCase();
if (v && !KEEP_POLICIES.has(v)) throw new UsageError(`--keep-policy must be one of: ${[...KEEP_POLICIES].join(', ')}`);

Type guard

const isKeepPolicy = (v: string): v is 'score_improvement' | 'pass_only' =>
  ['score_improvement', 'pass_only'].includes(v.trim().toLowerCase());

Try / catch

try { parseInitArgs(argv); } catch (e) { if (String(e.message).startsWith('--keep-policy')) { printUsage(); process.exit(2); } throw e; }

Prevention

When it happens

Trigger: Calling the CLI with `--keep-policy` in space-separated form, e.g. `autoresearch init --keep-policy best_of`, `--keep-policy PassOnly`, or `--keep-policy ""` (empty next token also skips the branch entirely, but any non-empty non-matching value throws).

Common situations: Typos like `score-improvement` or `pass-only` (hyphens instead of underscores), capitalized variants, or guessing a policy name like `always`/`all` that doesn't exist. Also passing extra values when copy-pasting from docs of a different version.

Related errors


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