spf13/cobraApache-2.0adbc881Report / request removal

Flag Groups: Required, One-Required, Mutually Exclusive

Flag groups let a command describe relationships among several flags instead of validating each flag independently. Cobra supports groups that require all participating flags together, require at least one member, or reject multiple members being set.

The relationship is recorded as flag annotations and later evaluated from each flag’s Changed state. This separates registration from validation: setup names the group, while validation decides whether the current invocation satisfies it.

Sources: flag_groups.go:33-45, flag_groups.go:49-61, flag_groups.go:65-77, flag_groups.go:81-109

Core concepts

Required-together group

A required-together group means that setting any member requires every member to be set. The public registration method is MarkFlagsRequiredTogether.

Sources: flag_groups.go:26, flag_groups.go:33-45

One-required group

A one-required group means that at least one member must be set, while setting multiple members is allowed by this group’s own validator. The public registration method is MarkFlagsOneRequired.

Sources: flag_groups.go:27, flag_groups.go:49-61, flag_groups.go:167-186

Mutually exclusive group

A mutually exclusive group means that zero or one member may be set, but two or more members are rejected. The public registration method is MarkFlagsMutuallyExclusive.

These three group kinds use distinct internal annotation keys and distinct status maps during validation.

GroupRegistration methodInternal annotationAccepted set counts
Required togetherMarkFlagsRequiredTogetherrequiredAsGroupAnnotationZero or all
One requiredMarkFlagsOneRequiredoneRequiredAnnotationOne or more
Mutually exclusiveMarkFlagsMutuallyExclusivemutuallyExclusiveAnnotationZero or one

Sources: flag_groups.go:28, flag_groups.go:65-77, flag_groups.go:188-207, flag_groups.go:26, flag_groups.go:27, flag_groups.go:81-109, flag_groups.go:33-45, flag_groups.go:49-61, flag_groups.go:144-165, flag_groups.go:167-186

How a group is registered

Each registration method first calls mergePersistentFlags, then looks up every supplied name through Flags().Lookup. If a name is missing, the method panics with a group-specific error.

For a required-together group, Cobra stores the space-joined flag list under requiredAsGroupAnnotation on every participating flag. Repeated registration appends another annotation entry, so the same flag can carry more than one group relationship.

MarkFlagsOneRequired follows the same annotation pattern using oneRequiredAnnotation. MarkFlagsMutuallyExclusive uses mutuallyExclusiveAnnotation, and its implementation explicitly allows a flag to belong to multiple groups.

This workflow shows the hand-off from public registration methods to annotations, then from annotations to validation.

Register and validate flag groups — How does a flag-group declaration become a validation result?

Evidence

Sources: flag_groups.go:33-45, flag_groups.go:49-61, flag_groups.go:65-77, flag_groups.go:26, flag_groups.go:27, flag_groups.go:28, flag_groups.go:81-109, flag_groups.go:121-142, flag_groups.go:144-165, flag_groups.go:167-186, flag_groups.go:188-207

How validation distinguishes the group kinds

ValidateFlagGroups returns immediately when DisableFlagParsing is enabled. Otherwise, it obtains c.Flags(), creates one status map for each group kind, visits every flag, and processes all three annotations for each flag.

The status maps use the joined flag list as a group identifier and map each flag name to a Boolean. processFlagForGroupAnnotation initializes a group only when hasAllFlags confirms that every named flag is defined; it then records each flag’s Changed value.

After collection, validation runs in a fixed order: required-together groups, one-required groups, then mutually exclusive groups. The first returned error stops the method; otherwise, ValidateFlagGroups returns nil.

For required-together groups, an invocation is valid when none or all members are set. If only some are set, the validator sorts the missing names and returns an error shaped like: if any flags in the group [%v] are set they must all be set; missing %v.

For one-required groups, the validator collects set members and accepts the group when the count is at least one. If the count is zero, the user sees an error shaped like: at least one of the flags in the group [%v] is required.

For mutually exclusive groups, the validator accepts zero or one set member. When two or more are set, it returns an error shaped like: if any flags in the group [%v] are set none of the others can be; %v were all set.

The following call order is visible inside ValidateFlagGroups; the supplied excerpts do not show a caller from Execute or ExecuteC, so they do not establish the exact command-execution phase in which that method is invoked.

Validation order — How are group constraints checked?

Evidence

Sources: flag_groups.go:81-109, flag_groups.go:121-142, flag_groups.go:144-165, flag_groups.go:167-186, flag_groups.go:188-207

Completion behavior

Completion uses a separate method, enforceFlagGroupsForCompletion, and also returns immediately when DisableFlagParsing is enabled. It builds the same three categories of group status and processes annotations from every flag.

When a required-together group has one flag set, completion marks the group’s flags as required through MarkFlagRequired. When a one-required group has no flag set, completion marks every member as required.

When a mutually exclusive group has one member set, completion looks up the other members and marks them hidden, while leaving the already-set flag visible. This affects suggestions; it is distinct from the validation errors returned by ValidateFlagGroups.

Sources: flag_groups.go:225-290, flag_groups.go:81-109

How it connects

Flag-group registration operates on the command’s merged flag view through mergePersistentFlags and c.Flags(), so it belongs with the repository’s broader flag layering and parsing behavior described in Flag Parsing & Persistent Flags.

The separate completion path uses parsed flag state and completion-specific required annotations, connecting group-aware suggestions to Dynamic Completion Engine.

For the broader command lifecycle, this page identifies ValidateFlagGroups as the group-validation entry point, but the supplied excerpts do not show its caller. Use Command Execution Flow for the surrounding execution sequence.

Sources: flag_groups.go:33-45, flag_groups.go:49-61, flag_groups.go:65-77, flag_groups.go:225-290, flag_groups.go:81-109

Key takeaways

  • Use MarkFlagsRequiredTogether when setting one flag should require all members.
  • Use MarkFlagsOneRequired when at least one member must be set.
  • Use MarkFlagsMutuallyExclusive when no more than one member may be set.
  • ValidateFlagGroups evaluates the three group types in required, one-required, then exclusive order.
  • The provided source shows the validation method and its internal order, but not its caller in command execution.

Want this for your repos?

Try Angada AI Wiki