Command Tree & Registration
Cobra models each CLI command as a Command value whose fields describe its syntax, documentation, completion behavior, validation, and execution handlers. Commands become navigable only after they are registered as children of another command.
This tree gives execution a stable way to map command-line tokens to a runnable leaf, while allowing parents to provide inherited context, flags, help, and path information.
Sources: command.go:54-260, command.go:1342-1368, command.go:892-897, command.go:1084-1170
Core concepts
Command definition
A command definition combines the user-facing syntax, metadata, argument policy, and work performed when the command runs. The central type is Command.
When defining a new subcommand, these are the fields that matter most:
| Field | Purpose | Typical question |
|---|---|---|
Use | Declares the command’s usage line and supplies its primary name. | What syntax should users type? |
Aliases | Provides alternate names for the first word in Use. | Which equivalent names should resolve? |
SuggestFor | Names inputs for which this command should be suggested rather than matched directly. | Which likely typos deserve a suggestion? |
Short | Supplies the short description used in help output. | What should appear in a command list? |
Long | Supplies the detailed help description. | What should help explain? |
Example | Holds command usage examples. | What valid invocation should users copy? |
Args | Selects the positional-argument validator. | What arguments are accepted? |
Run / RunE | Supplies the normal execution handler, with RunE able to return an error. | What work does the command perform? |
GroupID | Associates the subcommand with a help-output group. | Under which parent help section should it appear? |
ValidArgs / ValidArgsFunction | Supplies static or dynamic non-flag completion values. | What positional values can completion offer? |
These fields are declared directly on Command; the execution handlers and argument validator are distinct from display and completion metadata.
A command is runnable when either Run or RunE is present, and it is considered to have subcommands when its child list is non-empty.
Sources: command.go:54-260, command.go:64-100, command.go:117-146, command.go:1596-1598, command.go:1601-1603
Parent link
A parent link is the pointer from a child command back to the command that registered it. The link is exposed by Parent, while HasParent reports whether it exists.
Sources: command.go:1892-1894, command.go:1677-1679
Root command
The root command is the highest ancestor reached by repeatedly following Parent; Root returns the current command when no parent remains.
Sources: command.go:892-897
Registration
Registration is the act of calling AddCommand on a parent with one or more child pointers. It records the parent link, updates help-layout measurements, propagates global flag-name normalization, and appends the child to the parent’s command list.
Sources: command.go:1342-1368
How a command definition becomes a tree
AddCommand performs one structural validation: it rejects a command being added as a child of itself. It does not reject duplicate names in the shown implementation.
For each child, registration sets cmds[i].parent = c, measures the child’s Use, CommandPath, and Name, then updates the parent’s maximum lengths used by help formatting. Those measurements support padding such as UsagePadding, CommandPathPadding, and NamePadding, which read the parent’s recorded maxima.
If the parent has a global normalization function, AddCommand applies it to the new child through SetGlobalNormalizationFunc; that setter updates the child’s local and persistent flag sets and recursively propagates to existing descendants.
Finally, the child is appended to c.commands and the sorted-state marker is cleared. Commands sorts the list by name the next time sorting is enabled and the list is marked unsorted.
The following diagram shows the structural hand-off performed during registration.
Evidence
- parent-commandcommand.go:1342
- child-commandcommand.go:54
- parent-linkcommand.go:1347
- child-listcommand.go:1332
A command can be detached with RemoveCommand, which clears the removed child’s parent pointer, rebuilds the child slice, and recomputes the parent’s maximum lengths.
Sources: command.go:1342-1348, command.go:1347-1360, command.go:563-568, command.go:573-578, command.go:583-588, command.go:1361-1364, command.go:382-390, command.go:1365-1366, command.go:1332-1339, command.go:1342-1368, command.go:1401-1431
How Cobra finds the leaf command
Execution starts at the root even when ExecuteC is called on a descendant: if the current command has a parent, ExecuteC replaces it with Root().ExecuteC(). The input comes from SetArgs when explicitly supplied; otherwise, ExecuteC uses os.Args[1:] except for the shown test-process workaround.
Before lookup, ExecuteC initializes completion and default completion commands, validates command groups, and selects between Traverse and Find according to TraverseChildren.
Find removes flag arguments from consideration, takes the first remaining token as the next subcommand name, resolves it with findNext, and recursively continues with the remaining arguments. findNext accepts a matching name or alias, and may accept a unique name-or-alias prefix when EnablePrefixMatching is enabled. Alias and name comparison can use case-insensitive matching when EnableCaseInsensitive is enabled.
If no deeper child matches, Find returns the deepest command found and leaves the remaining arguments for that command. When the command has no explicit Args validator, it applies legacy argument handling; a root with subcommands reports an unknown command for an unmatched first argument.
The alternate Traverse path scans arguments while preserving flag values, parses flags before descending, and recursively traverses the remaining tokens. A long or short flag that expects a separate value causes the next token to be treated as that value rather than as a subcommand.
The lookup path is summarized below.
Evidence
- process-argumentscommand.go:1102
- root-executioncommand.go:1084
- command-searchcommand.go:757
- child-matchcommand.go:798
- leaf-commandcommand.go:1137
The call order after lookup is: ExecuteC selects a command, records how it was called, passes context if needed, and calls execute with the remaining flags and arguments.
Evidence
- execute-ccommand.go:1084
- find-or-traversecommand.go:1119
- selected-commandcommand.go:1144
Sources: command.go:1084-1093, command.go:1102-1107, command.go:1109-1124, command.go:757-771, command.go:798-817, command.go:1928-1934, command.go:774-778, args.go:25-37, command.go:821-858, command.go:1084-1170, command.go:757-779, command.go:1137-1148
How it connects
Execution consumes the tree through ExecuteC, then the selected command enters flag parsing, argument validation, hooks, and its Run or RunE handler; see Command Execution Flow.
Flag visibility follows the same ancestry: persistent flags are merged from the command and its parents before parsing or local/inherited flag inspection; see Flag Parsing & Persistent Flags.
Help and usage walk Commands, filter available children, and build paths with CommandPath; see Help, Usage & Templates. Completion also resolves command paths through Find and Traverse; see Dynamic Completion Engine.
Documentation generators consume the same parent/child tree and command paths to emit pages for descendants; see Man Page & Markdown Doc Generation and REST & YAML Doc Generation.
Sources: command.go:905-1045, command.go:1084-1170, command.go:1898-1902, command.go:1744-1766, command.go:1868-1889, command.go:1974-2040, command.go:1465-1470, command.go:1263-1314, doc/md_docs.go:119-132, doc/rest_docs.go:132-144
Key takeaways
- Define
Use, metadata, argument validation, completion fields, and aRunorRunEhandler for a subcommand. AddCommandsets the parent link, updates formatting measurements, propagates normalization, and appends the child.Findrecursively strips flags and matches names, aliases, or configured unique prefixes.Traverseis the flag-aware alternative selected byTraverseChildren.Root,Parent, andCommandPathprovide ancestry and fully qualified command identity.