spf13/cobraApache-2.0adbc881Report / request removal

Positional Argument Validators

Cobra validates non-flag command-line arguments through a PositionalArgs function: a callable that receives the command and parsed arguments, then returns either an error or nil.

This layer exists so commands can choose a precise argument policy instead of accepting every positional value indiscriminately. The built-in validators cover empty, bounded, exact, unique, and valid-name argument sets, and they can be composed when one rule is not enough.

Sources: args.go:22, args.go:42-47, args.go:69-79, args.go:107-114, args.go:127-136

Core concepts

Positional argument policy

A positional argument policy is the function stored in a command’s Args field and executed by ValidateArgs. If Args is nil, ValidateArgs calls ArbitraryArgs; otherwise it calls the configured validator.

Sources: command.go:1172-1177

Valid argument names

A command’s ValidArgs field is the list checked by OnlyValidArgs; entries may contain a tab-separated description, but only the text before the tab is treated as the accepted argument.

Sources: args.go:51-66

Validator composition

MatchAll creates one PositionalArgs validator that runs each supplied validator in order and returns the first error.

Sources: args.go:127-136

How validation is selected

The validation entry point chooses permissive behavior only when the command has no configured Args validator; otherwise it delegates to that validator. This makes ArbitraryArgs the behavior of a nil Args field, while explicit validators such as NoArgs impose stricter rules.

Selecting argument validation — Which validator runs for a command?

Evidence

The important distinction is between three permissiveness policies. ArbitraryArgs always returns nil, so it accepts any argument list. NoArgs rejects every non-empty list and reports the first value as an unknown command. legacyArgs is conditional: it accepts arguments for commands without subcommands, but for a root command with subcommands it rejects a non-empty argument list and may include a suggestion.

PolicyAccepted inputRejection condition
ArbitraryArgsEvery argument listNever rejects
NoArgsOnly an empty listAt least one argument
legacyArgsAny list when there are no subcommandsRoot command with subcommands and at least one argument
MinimumNArgsAt least n argumentsFewer than n
MaximumNArgsAt most n argumentsMore than n
ExactArgsExactly n argumentsCount differs from n
RangeArgsBetween min and max, inclusiveCount is outside the range
NoDuplicateArgsLists with unique valuesAny value occurs more than once

Sources: command.go:1172-1177, args.go:82-84, args.go:42-47, args.go:28-39, args.go:69-79, args.go:87-94, args.go:97-104, args.go:107-114, args.go:117-124

How the built-in validators enforce rules

Count-based validators inspect only len(args). MinimumNArgs checks the lower bound, MaximumNArgs checks the upper bound, ExactArgs requires equality, and RangeArgs checks both bounds. Each returns nil when its condition is satisfied and an error containing the expected and received counts otherwise.

NoDuplicateArgs tracks each argument in a map and returns an error as soon as it encounters a value already seen. This is useful when repeated positional values would change the command’s meaning.

NoArgs is different from a generic count error: it formats the first supplied value as an unknown command and includes the command path.

Sources: args.go:87-94, args.go:97-104, args.go:107-114, args.go:117-124, args.go:69-79, args.go:42-47

How validators are combined

Use MatchAll when a command needs independent rules over the same argument list. It receives one or more PositionalArgs values, invokes them in order, stops at the first error, and returns nil only if all validators succeed.

Running combined validators — How does MatchAll apply multiple argument rules?

Evidence

A common composition is exactness plus membership. ExactValidArgs is defined as MatchAll(ExactArgs(n), OnlyValidArgs), so it requires exactly n arguments and then checks that each supplied value is valid.

The order matters because MatchAll runs validators in the order supplied. With ExactValidArgs, the count rule runs before the valid-name rule; with a custom MatchAll ordering, the first failing policy determines the returned error.

Sources: args.go:127-136, args.go:142-144

How OnlyValidArgs uses ValidArgs

OnlyValidArgs performs membership validation only when cmd.ValidArgs is non-empty. It first removes descriptions by splitting each entry at the first tab, then checks every supplied argument against the resulting names.

If an argument is absent from that cleaned list, the validator returns an error containing the invalid value, the command path, and suggestions produced by findSuggestions. If cmd.ValidArgs is empty, the validator returns nil without checking the arguments.

This validator is about execution-time acceptance, not merely completion display: the command’s ValidArgs field supplies the names against which OnlyValidArgs compares user input. Separately, Cobra’s completion path also completes ValidArgs when the field is populated, including for commands that have subcommands.

Sources: args.go:51-66, completions.go:533-535

How it connects

Argument validation is one part of the command model described in Cobra Overview. A command stores its positional policy in Args, while the command tree and command path provide the context used in validation errors.

The selection of the command and its arguments occurs within the broader execution sequence described in Command Execution Flow. ValidateArgs is the local hand-off from command execution to the configured positional policy.

ValidArgs also participates in shell completion, whose dynamic and static mechanisms are described in Dynamic Completion Engine. The same field can therefore define accepted names for OnlyValidArgs and provide completion candidates.

Sources: command.go:87-98, args.go:42-47, args.go:51-66, command.go:1172-1177, completions.go:533-535

Key takeaways

  • ArbitraryArgs accepts every argument list, NoArgs accepts none, and legacyArgs changes behavior based on subcommands.
  • A nil Args field makes ValidateArgs call ArbitraryArgs; a configured field calls its PositionalArgs validator.
  • MatchAll applies validators in order and stops at the first error.
  • OnlyValidArgs checks supplied values against cleaned entries from ValidArgs.
  • ExactValidArgs combines exact count validation with valid-name validation.

Sources: args.go:28-39, args.go:42-47, args.go:82-84, command.go:1172-1177, args.go:127-136, args.go:51-66, args.go:142-144

Want this for your repos?

Try Angada AI Wiki