fix(config): allow setting a string option to an empty value - #9963
Open
SomSamantray wants to merge 1 commit into
Open
fix(config): allow setting a string option to an empty value#9963SomSamantray wants to merge 1 commit into
SomSamantray wants to merge 1 commit into
Conversation
`npm config set <key> ""` deleted the key instead of persisting an empty string, because `keyValues()` collapsed "no value given" and "explicitly empty value" into the same `''` fallback and `set()` mapped `''` to `config.delete()`. Options that are meaningful when empty, such as `tag-version-prefix`, could not be set to an empty value from the CLI. Use a `null` sentinel for a value that was omitted entirely so the two intents stay distinct. An explicit empty value is persisted only for options whose type is `String`, since that is the only type for which an empty string is a real value. For every other type an empty value keeps removing the key, as it did before, because parsing coerces it to `true` for `Boolean` options, to `0` for `Number` options, and rejects it for URL and enum options. Keys without a definition, such as a nerf-darted credential, also keep removing the key.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
npm config set <key> ""silently deleted the key instead of persisting an emptystring, because
keyValues()collapsed "no value given" and "explicitly emptyvalue" into the same
''fallback, andset()mapped''toconfig.delete().This made the documented
tag-version-prefix=""workflow unreachable from the CLI:config options that are meaningful when empty could not be set to empty. It has
been broken since npm v9.6.5, when the
val === ''delete branch was introducedalongside the matching docs sentence.
What this changes
lib/commands/config.jsnow uses anullsentinel for a value that was omittedentirely, so the two intents stay distinct:
npm config set <key>— value omitted, the key is removed (unchanged)npm config set <key> ""— an explicit empty string, persisted as<key>=An empty value is only persisted for options whose type is
String, since that isthe only type for which an empty string is a real value. For every other type an
empty value keeps removing the key, which is exactly what it did before this
change. This matters because config parsing coerces an empty string to
trueforBooleanoptions and to0forNumberoptions, and rejects it for URL and enumoptions — so persisting it generally would mean
npm config set save-exact ""silently enables
save-exact, andnpm config set registry "$UNSET_VAR"wouldwrite
registry=and make every later npm command fail withERR_INVALID_URL.Keys with no definition, such as a nerf-darted credential, also keep deleting.
The delete branch keys off whether the value is usable rather than whether it is
literally empty, and the debug log line still reports
""for an omitted value soexisting verbose output is unchanged. An empty value was already handled correctly
everywhere downstream — this only fixes the path that never let one through.
One small semantic consequence worth flagging: values are trimmed as before, so
npm config set tag-version-prefix " "is treated as an explicit empty value fora string option and now persists the empty string instead of deleting the key. For
non-string options a whitespace-only value still deletes, as it did before. Happy to
change this if you would rather a whitespace-only value keep meaning "remove".
Verification
npm config set tag-version-prefix ""followed bynpm version patchin a gitrepo now prints
1.0.1and creates the1.0.1git tag and commit message, with novprefix.npm config set tag-version-prefixstill removes the key andnpm config getfalls back to thevdefault.Typed options are unchanged: after
npm config set save-exact "",npm config get save-exactis stillfalse(nottrue);fetch-retriesstays atits default
2(not0); andregistrykeeps its default with subsequentcommands working normally.
npx tap test/lib/commands/config.js --no-coverage— passnode . run eslint— passnode . run test— passThe tests cover the explicit empty value, the
key=form, a mixed invocation thatpairs an empty value with an omitted key, and one case per non-string option type
(
Boolean,Number, URL, enum); the existing omitted-value deletion test stillpasses unchanged.
References
Fixes #6719