can1357/oh-my-pi · error · Error

Invalid --source: ${args.source}. Expected one of: ${TTSR_SO

Error message

Invalid --source: ${args.source}. Expected one of: ${TTSR_SOURCES.join(", ")}

What it means

`omp ttsr test` accepts `--source` to set the match context origin, which must be one of the enumerated TTSR_SOURCES values: text, thinking, or tool. runTest validates the raw string before use; anything else throws this error listing the allowed values. This is an argument-validation guard so an invalid source never silently alters rule scoping.

Source

Thrown at packages/coding-agent/src/cli/ttsr-cli.ts:338

		builtinRules: true,
		disabledRules: [],
	});
	if (!manager.addRule(rule)) {
		throw new Error(
			`Rule "${rule.name}" has no usable TTSR condition. Add a \`condition\` (regex) or \`astCondition\` (ast-grep pattern) to its frontmatter.`,
		);
	}
	return { rules: manager.getRules(), manager };
}

async function loadIsolatedScanRule(rulePath: string): Promise<Rule[]> {
	const rule = await readIsolatedRule(rulePath);
	return filterTtsrRulesForScan([rule]);
}

async function runTest(args: TtsrTestArgs, json: boolean, cwd: string): Promise<void> {
	if (args.source && !TTSR_SOURCES.includes(args.source)) {
		throw new Error(`Invalid --source: ${args.source}. Expected one of: ${TTSR_SOURCES.join(", ")}`);
	}

	const snippet = await readSnippet(args);

	// Infer match context: when the user points --file at a source file and
	// doesn't pick a source, default to tool/edit with that path so tool-scoped
	// rules (the common case, e.g. tool:edit(*.ts)) match like they would live.
	const filePath = args.filePath ?? (args.file && args.file !== STDIN_MARKER ? path.resolve(args.file) : undefined);
	const source: TtsrMatchSource =
		args.source ?? (filePath && SOURCE_FILE_EXT.test(path.extname(filePath)) ? "tool" : "text");
	const tool = args.tool ?? (source === "tool" ? "edit" : undefined);

	// A supplied source file whose extension is unknown falls through to the
	// text (prose) context, where tool-scoped rules can never match. Surface
	// that so a false negative reads as a context mismatch, not a bad regex.
	const inferenceNote =
		!args.source && filePath && source === "text"
			? `inferred --source text from '${path.extname(filePath) || filePath}' (not in the source-file extension set); pass --source tool --tool edit to evaluate tool-scoped rules`

View on GitHub (pinned to 9690622007)

Solutions

  1. Use one of: `--source text`, `--source thinking`, or `--source tool`.
  2. If you meant to name a tool like edit/write, pass it via `--tool` together with `--source tool`.
  3. Mind case sensitivity — values are lowercase.
  4. Omit --source entirely to let the CLI infer it from --file (tool for source files, text otherwise).

Example fix

// before
omp ttsr test --snippet "..." --source edit --tool edit
// after
omp ttsr test --snippet "..." --source tool --tool edit
Defensive patterns

Strategy: validation

Validate before calling

const SOURCES = ["text", "thinking", "tool"] as const;
if (args.source && !SOURCES.includes(args.source)) {
  throw new Error(`--source must be one of ${SOURCES.join("|")}`);
}

Type guard

function isTtsrSource(v: string): v is TtsrMatchSource {
  return (TTSR_SOURCES as readonly string[]).includes(v);
}

Try / catch

try {
  await runTtsrCommand(args);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Invalid --source:")) {
    console.error(`${err.message} (values are lowercase)`);
    process.exitCode = 2;
  } else throw err;
}

Prevention

When it happens

Trigger: Running `omp ttsr test ... --source <value>` where value is not exactly `text`, `thinking`, or `tool` — typos like `tools`, `Text` (case-sensitive), `editor`, or passing a tool name to --source instead of --tool.

Common situations: Confusing --source with --tool (e.g. `--source edit` instead of `--tool edit`); autocomplete/history from a different command's flag values; shell variable interpolation injecting an unexpected value.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/1ab38f9260197b91. Report an issue: GitHub.