ReactiveX/rxjs · error · Error
Usage: rxjs-migrate-skill <check|install|update|remove>…
Error message
Usage: rxjs-migrate-skill <check|install|update|remove> --harness <codex|claude|cursor> [--project-root <dir>] [--force]
What it means
Thrown by parseSkillArguments when the first CLI argument is not one of check, install, update, or remove. The skill CLI is strict about its action verb and prints usage in the error message.
Solutions
- Use exactly one of: rxjs-migrate-skill check|install|update|remove
- Put the action first, before --harness and other flags
- Check the CLI help/usage string for the accepted verbs
Example fix
# before rxjs-migrate-skill install-skill --harness claude # after rxjs-migrate-skill install --harness claude
Defensive patterns
Strategy: validation
Validate before calling
const actions = ['check','install','update','remove'] as const;
if (!actions.includes(argv[0] as any)) { console.error('Usage: ...'); process.exit(2); } Type guard
const isSkillAction = (a: string): a is 'check'|'install'|'update'|'remove' => ['check','install','update','remove'].includes(a);
Prevention
- Read the usage string before scripting
- Put the action verb first
When it happens
Trigger: Running rxjs-migrate-skill with no arguments, a misspelled action ('instal', 'list'), or an action in the wrong position (after flags).
Common situations: Typos, forgetting the action, or assuming a 'list'/'init' subcommand exists.
Understand the failure class
Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.
Related errors
- --harness is required
- --harness requires codex, claude, or cursor
- --project-root requires a directory
- Unknown option
- Cannot locate the canonical Skill shipped by @rxjs/migrate.
AI-assisted analysis of ReactiveX/rxjs@54796b38a5 (2026-08-28).
Data as JSON: /api/errors/eab6d3ebd88e410f.
Report an issue: GitHub.
Appendix: source
Thrown at packages/migrate/src/skill-cli.ts:73
export async function resolveCanonicalSkillRoot(modulePath = process.argv[1]): Promise<string> {
if (!modulePath) throw new Error('Cannot locate the @rxjs/migrate package entry point.');
const moduleDirectory = dirname(resolve(modulePath));
for (const localPath of ['../skill', '../../skill']) {
const candidate = resolve(moduleDirectory, localPath);
try {
if ((await stat(join(candidate, 'SKILL.md'))).isFile()) return candidate;
} catch {
// Try the source-tree or built-package alternative.
}
}
throw new Error('Cannot locate the canonical Skill shipped by @rxjs/migrate.');
}
function parseSkillArguments(argv: readonly string[]): ParsedSkillCliOptions {
const action = argv[0];
if (action !== 'check' && action !== 'install' && action !== 'update' && action !== 'remove') {
throw new Error(
'Usage: rxjs-migrate-skill <check|install|update|remove> --harness <codex|claude|cursor> [--project-root <dir>] [--force]'
);
}
let harness: SkillHarness | undefined;
let projectRoot = process.cwd();
let force = false;
for (let index = 1; index < argv.length; index++) {
const argument = argv[index];
if (argument === '--harness') {
const value = argv[++index];
if (!value || !skillHarnesses.includes(value as SkillHarness)) throw new Error('--harness requires codex, claude, or cursor');
harness = value as SkillHarness;
} else if (argument === '--project-root') {
const value = argv[++index];
if (!value) throw new Error('--project-root requires a directory');
projectRoot = value;
} else if (argument === '--force') {
force = true;View on GitHub (pinned to 54796b38a5)