yargs Unknown Argument — CLI Rejects a Valid Flag
Fix yargs strict-mode Unknown argument errors by declaring the flag, using coerce, and understanding camelCase and dashed aliases.
Symptoms
- The CLI prints "Unknown arguments: long-flag, longFlag" and exits
- A flag that used to work after an upgrade now errors
- --flag=true is rejected while --flag true works
Possible causes
- strict() is enabled and the flag is not declared in the command builder
- The option is declared with a dashed name while users pass camelCase, or vice versa without alias
- A boolean option is given a value with = while the parser expects a space-separated form
Diagnosis steps
Reproduce with the exact invocation
node cli.js deploy --env=prodInterpretation
The error names every unknown token, so you can map it straight to a missing .option() declaration.
Inspect declared options
node -e "const y=require('yargs/yargs')(['node','x']); console.log(y.option('env').getOptions())"Interpretation
Confirms whether the option and its alias exist. Add alias entries to accept both spellings.
Root cause
yargs strict() fails the run when it encounters a token that matches no declared option. Dashed and camelCase spellings are distinct unless an alias links them, so a declared --dry-run does not automatically accept --dryRun under strict mode.
Fix
Declare every intended flag, add aliases for common alternate spellings, and use .strict() together with .demandCommand() so typos fail loudly instead of being ignored. For pass-through data, add .parserConfiguration or use .strict(false) selectively.
Risk note
Disabling strict mode globally turns typos into silently ignored flags, which is worse than a hard failure in CI.
Verify the fix
Rerun the previously failing invocation and confirm it parses. Then run a deliberately misspelled flag and confirm it still fails, proving strictness is preserved.
Symptoms
When you hit “yargs Unknown Argument — CLI Rejects a Valid Flag”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.
Observed symptoms include:
- The CLI prints “Unknown arguments: long-flag, longFlag” and exits
- A flag that used to work after an upgrade now errors
- –flag=true is rejected while –flag true works
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Reproduce with the exact invocation
node cli.js deploy --env=prod
The error names every unknown token, so you can map it straight to a missing .option() declaration.
Step 2: Inspect declared options
node -e "const y=require('yargs/yargs')(['node','x']); console.log(y.option('env').getOptions())"
Confirms whether the option and its alias exist. Add alias entries to accept both spellings.
Likely contributors, in order of frequency:
- strict() is enabled and the flag is not declared in the command builder
- The option is declared with a dashed name while users pass camelCase, or vice versa without alias
- A boolean option is given a value with = while the parser expects a space-separated form
Root Cause
yargs strict() fails the run when it encounters a token that matches no declared option. Dashed and camelCase spellings are distinct unless an alias links them, so a declared –dry-run does not automatically accept –dryRun under strict mode.
The Fix
Declare every intended flag, add aliases for common alternate spellings, and use .strict() together with .demandCommand() so typos fail loudly instead of being ignored. For pass-through data, add .parserConfiguration or use .strict(false) selectively.
Watch out: Disabling strict mode globally turns typos into silently ignored flags, which is worse than a hard failure in CI.
#!/usr/bin/env node
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
yargs(hideBin(process.argv))
.command('deploy', 'deploy the app', (y) =>
y.option('env', { type: 'string', alias: 'e', choices: ['dev', 'prod'], demandOption: true })
.option('dry-run', { type: 'boolean', alias: 'dryRun' }),
)
.strict()
.demandCommand(1)
.parse();
Verify and Prevent
Rerun the previously failing invocation and confirm it parses. Then run a deliberately misspelled flag and confirm it still fails, proving strictness is preserved.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.