Version: effect 4.0.0-beta.101
What happens
The parser silently drops positional arguments that no declared param consumes, and no combinator can make it fail:
import { Command, Argument } from "effect/unstable/cli"
// Command with no arguments:
const init = Command.make("init", {})
// `mycli init extra` succeeds — "extra" is silently ignored
// Command with a single positional:
const run = Command.make("run", { prompt: Argument.string("prompt") })
// `mycli run "hi" oops` succeeds with prompt = "hi" — "oops" is silently ignored
// Cardinality combinators don't help:
Argument.string("prompt").pipe(Argument.between(1, 1)) // or atMost(1)
// max only stops consuming; the extra positional is still silently dropped
Cause
internal/command.js parseParams threads currentArguments through each declared param and discards whatever remains after the loop — there is no "unexpected argument" check.
Param.js parsePositionalVariadic enforces min with an error but treats max purely as a stop-consuming bound.
Why this looks like a bug
- Asymmetric with flags: unknown flags raise
UnrecognizedOption, and parseOptionVariadic fails with InvalidValue when occurrences exceed max — positionals do neither.
- Regression from v3: stable
@effect/cli documented a ValidationError for excess arguments.
Suggested fix
Fail the parse when positionals remain unconsumed after parseParams, and/or make positional max reject extras the way flag max does.
Version: effect 4.0.0-beta.101
What happens
The parser silently drops positional arguments that no declared param consumes, and no combinator can make it fail:
Cause
internal/command.jsparseParamsthreadscurrentArgumentsthrough each declared param and discards whatever remains after the loop — there is no "unexpected argument" check.Param.jsparsePositionalVariadicenforcesminwith an error but treatsmaxpurely as a stop-consuming bound.Why this looks like a bug
UnrecognizedOption, andparseOptionVariadicfails withInvalidValuewhen occurrences exceedmax— positionals do neither.@effect/clidocumented aValidationErrorfor excess arguments.Suggested fix
Fail the parse when positionals remain unconsumed after
parseParams, and/or make positionalmaxreject extras the way flagmaxdoes.