New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Yargs v17 calls coerce with undefined when option is not passed #2130
Comments
Just to illustrate with an example of one difference in v17 which doesn't seem right (or at least, I didn't anticipate it based on the changelog): const yargs = require('yargs');
let args = yargs
.strict()
.option('abc', {
boolean: true
})
.option('xyz',{
implies: ['abc'],
// removing this coerce method will avoid errors when no params are passed
coerce: (val) => val && val.toLowerCase()
});
console.log('////yargs x.y.z////');
console.log(JSON.stringify(args)); Based on the above, since option 'abc' isn't a required option, I would expect to be able to pass no arguments. This is the case in v16: $ node index.js
////yargs 16.2.0////
{"$0":"index.js","parsed":false,"argv":{"_":[],"$0":"index.js"}} In v17, however, the combination of the requires relationship and the coerce causes a "Missing dependent arguments" error: $ node index.js
////yargs 17.3.0////
Options:
--help Show help [boolean]
--version Show version number [boolean]
--abc [boolean]
--xyz
Missing dependent arguments:
xyz -> abc As another related bit of information here, when no
Given that there's no dependents error for the implies relationship in v17 after merely removing the coerce method, it seems that this new behavior isn't the desired one. Is this a bug? Thanks! |
@dsamerotte this sounds like an unintended breaking change, which would be good to fix. |
Should be fixed in 17.4.1. |
Closing as fixed by #2161. |
Per #1219, yargs has not historically called
coerce
when the associated option is not passed. However, when porting my code to v17, I see that this is no longer the case, and I'm wondering whether this is an intentional breaking change or a regression. The only potentially relevant breaking change that I see in the release notes is that "coerce is now applied before validation," but I wouldn't expect this change in behavior from that description alone.I understand that yarg's middleware underwent substantial changes in v17. Based on my two-second investigation, it looks like v16 maps over the supplied options and then calls coerce as needed, such that coerce can never receive
undefined
. However, v17 instead appears to reduce all middleware without checking the existence of the related option.The obvious result is that code like
.coerce('dir', path.resolve)
, which still appears in the docs, no longer works, and client code now needs to explicitly check forundefined
.If this is an intentional change, should this also affect subcommand processing? I'm even seeing coerce called like this in parent commands when calling only a subcommand and when the parent option is not passed and is marked as
global: false
. If I understand theglobal
option correctly, this seems especially strange.I thought I'd keep this short and start with the high-level question first. Based on the answer, I can, of course, provide additional thoughts and information. Thanks!
The text was updated successfully, but these errors were encountered: