can1357/oh-my-pi · error · CliError

${message}

Error message

${message}

What it means

`usage()` is the CLI argument-parsing failure path in the mnemopi CLI. It throws a `CliError` with exit code 2 whenever the command line is malformed — bad subcommand, missing/extra arguments, or invalid flag values. The error message is printed by the top-level CLI handler instead of a stack trace.

Source

Thrown at packages/mnemopi/src/cli.ts:50

	}
}

type CommandHandler = (args: readonly string[], context?: CliContext) => number | Promise<number>;

function out(context: CliContext | undefined, text = ""): void {
	(context?.stdout ?? Bun.stdout).write(`${text}\n`);
}

function err(context: CliContext | undefined, text = ""): void {
	(context?.stderr ?? Bun.stderr).write(`${text}\n`);
}

function fail(message: string, exitCode = 2): never {
	throw new CliError(`Error: ${message}`, exitCode);
}

function usage(message: string): never {
	throw new CliError(message, 2);
}

function parseFloatArg(value: string, name: string): number {
	const parsed = Number(value);
	if (!Number.isFinite(parsed)) fail(`${name} must be a number: ${value}`);
	return parsed;
}

function parseIntArg(value: string, name: string): number {
	if (!/^[+-]?\d+$/.test(value)) fail(`${name} must be an integer: ${value}`);
	const parsed = Number(value);
	if (!Number.isSafeInteger(parsed)) fail(`${name} must be an integer: ${value}`);
	return parsed;
}

function resolveDataDir(context?: CliContext): string {
	return context?.dataDir ?? configuredDataDir();
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Run the CLI with `--help` (or no args) and use the documented syntax for the subcommand.
  2. Check the exact argument name and order expected by the subcommand in the CLI source (`packages/mnemopi/src/cli.ts`).
  3. In scripts, quote/validate values before passing them (e.g. ensure numeric args are finite numbers).
  4. Update any wrapper scripts that target a deprecated or renamed subcommand.

Example fix

// before
bun cli annotate --bank my bank --score ten
// after
bun cli annotate --bank my-bank --score 10
Defensive patterns

Strategy: validation

Validate before calling

const args = process.argv.slice(2);
const VALID = new Set(["annotate", "search", "bank", "import", "export"]);
if (!VALID.has(args[0])) {
  console.error(`Unknown subcommand: ${args[0]}. Run with --help.`);
  process.exit(2);
}

Type guard

null

Try / catch

try {
  runCli(argv);
} catch (err) {
  if (err instanceof CliError) {
    console.error(err.message);
    process.exit(err.exitCode);
  }
  throw err;
}

Prevention

When it happens

Trigger: Running the CLI with an unknown subcommand, a missing required argument, an unrecognized flag, or an argument that fails parsing (e.g. `parseFloatArg` companion `fail()` is used for non-numeric numeric options).

Common situations: Typo'd subcommands in shell scripts or CI pipelines, calling the CLI with Python-style flag names or old syntax after an upgrade, forgetting required positional args, passing a non-numeric value to a numeric option.

Related errors


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