You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cli: parseArgs() treats an empty flag value passed without "=" as a positional argument #7351
When an empty string is given as the value of a flag as a separate argument (--foo ""), parseArgs() sets the flag to "" but also pushes the same "" into _.
I'd like to take this. Root cause is in cli/parse_args.ts in the long-flag branch of the �rgs loop:
s const next = args[i + 1]; if (next) { // <-- truthiness check if (!booleanSet.has(key) && !allBools && !next.startsWith("-") && ...) { value = next; i++; setArgument(key, value, arg, true); continue; } ... } value = stringSet.has(key) ? "" : true; // fallback: never consumes args[i+1] setArgument(key, value, arg, true);
For --foo "",
ext is "", so if (next) is false and the value arg is never consumed. The fallback then still sets oo to "" (because oo is in stringSet), but i is not incremented, so the stray "" is visited on the next iteration and lands in _ as a positional. The short-flag branch has the same shape at if (nextArg) (line 841).
Fix: use an explicit
ext !== undefined check (and likewise
extArg !== undefined) so an empty string is accepted as an option value; booleans are unaffected because the branch already excludes �ooleanSet/�llBools. I'll add a regression test in cli/parse_args_test.ts covering parseArgs(["--foo", ""], { string: ["foo"] }) === { _: [], foo: "" } plus a short-flag case, and run the std/cli suite. I'll open a PR once a maintainer confirms the direction.
Activity
Yusuf-Hussien commentedon Oct 8, 2026
I'd like to take this. Root cause is in cli/parse_args.ts in the long-flag branch of the �rgs loop:
s const next = args[i + 1]; if (next) { // <-- truthiness check if (!booleanSet.has(key) && !allBools && !next.startsWith("-") && ...) { value = next; i++; setArgument(key, value, arg, true); continue; } ... } value = stringSet.has(key) ? "" : true; // fallback: never consumes args[i+1] setArgument(key, value, arg, true);For --foo "",
ext is "", so if (next) is false and the value arg is never consumed. The fallback then still sets oo to "" (because oo is in stringSet), but i is not incremented, so the stray "" is visited on the next iteration and lands in _ as a positional. The short-flag branch has the same shape at if (nextArg) (line 841).
Fix: use an explicit
ext !== undefined check (and likewise
extArg !== undefined) so an empty string is accepted as an option value; booleans are unaffected because the branch already excludes �ooleanSet/�llBools. I'll add a regression test in cli/parse_args_test.ts covering parseArgs(["--foo", ""], { string: ["foo"] }) === { _: [], foo: "" } plus a short-flag case, and run the std/cli suite. I'll open a PR once a maintainer confirms the direction.