Skip to content

fix: ignore the configured default for an option with zero narg - #570

Closed
naveentehrpariya wants to merge 1 commit into
yargs:mainfrom
naveentehrpariya:fix-narg-zero-default
Closed

naveentehrpariya wants to merge 1 commit into
yargs:mainfrom
naveentehrpariya:fix-narg-zero-default

Conversation

@naveentehrpariya

Copy link
Copy Markdown

Fixes #418.

The bug

An option configured with narg: 0 takes no arguments, so passing it is a switch — the existing test should not use next value for boolean/number/string configured with zero narg asserts exactly that: bool → true, nr → undefined, str → ''.

But eatNargs produces that value through defaultValue(), which returns the configured default for any option that is not declared boolean or count:

function defaultValue (key: string) {
  if (!checkAllAliases(key, flags.bools) &&
      !checkAllAliases(key, flags.counts) &&
      `${key}` in defaults) {
    return defaults[key]
  }
  ...

So adding a default of false makes the option parse as false even when it is given on the command line:

parser(['-a', 'hello', '-b', 'world'], {
  narg: { a: 1, b: 0 },
  default: { b: false },
  alias: { blah: ['b', 'bl'] }
})

// actual
{ _: ['world'], a: 'hello', b: false, blah: false, bl: false }
// expected
{ _: ['world'], a: 'hello', b: true, blah: true, bl: true }

Declaring the option boolean: true works, which is why this only shows up for options that use narg to accept either a value or no value at all.

The fix

eatNargs now takes the value implied by the option's type directly, instead of going through defaultValue(). A default is the value an option takes when it is absent, so it should not be consulted for an option that was given.

Tests

  • An option with narg: 0 and a default of false parses as true (along with its aliases) when it is passed. Fails on main with expected … to have property 'b' of true, but got false.
  • The default still applies when the option is not passed.

npm test is 364 passing / 0 failing, npm run test:typescript 20 passing, npm run check clean.

An option configured with `narg: 0` takes no arguments, so passing it is
a switch and its value should be the one implied by its type. `eatNargs`
instead called `defaultValue`, which returns the configured `default` for
any option not declared `boolean` or `count`, so a `default` of `false`
made the option parse as `false` even when it was given:

    parser(['-b'], { narg: { b: 0 }, default: { b: false } })
    // => { b: false }, expected { b: true }

Use the type's value directly. The configured default still applies when
the option is absent.

Fixes yargs#418
@shadowspawn

Copy link
Copy Markdown
Member

Unsolicited Pull Requests may be closed without discussion.

For more see Contributing and AI Policy.

@shadowspawn shadowspawn closed this Nov 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Default value of false doesn't work for narg: { flag: 0 }

2 participants