Suggestions & Error Handling
Cobra turns command-line mistakes into structured errors, optionally augments unknown-command errors with suggestions, and routes execution failures through the command’s configured output writers. The important split is between finding a command and executing it: unknown-command handling happens during lookup, while RunE failures happen after lookup.
Cobra returns errors rather than universally terminating the process. An application can therefore decide whether to print, wrap, test, or convert an error into an exit code; the convenience function CheckErr is the explicit path that prints an error and calls os.Exit(1).
Sources: command.go:757-779, command.go:905-1045, command.go:1084-1170, command.go:1070-1073, cobra.go:235-240
Core concepts
Unknown command
An unknown command is a non-flag argument that cannot be matched to a child command during Find.
Sources: args.go:28-38, command.go:757-779
Suggestion candidate
A suggestion candidate is an available child command whose name is close to, starts with, or explicitly advertises itself for the mistyped name.
Sources: command.go:863-881, command.go:1607-1621
Execution error
An execution error is an error returned while Cobra parses flags, validates arguments, runs hooks, or invokes RunE/related execution callbacks.
Sources: command.go:905-1045, command.go:54-260
Silence controls
SilenceErrors controls Cobra’s automatic error line, while SilenceUsage controls the usage text printed for execution errors.
Sources: command.go:1084-1170
How Cobra chooses a suggestion
Find removes flag arguments, takes the next remaining token as the candidate subcommand, and recursively descends when findNext finds a match; if no child matches, lookup stops at the current command. The root-level legacy argument check then creates an unknown command error and appends the result of findSuggestions.
The suggestion search begins disabled when DisableSuggestions is true; otherwise, a non-positive SuggestionsMinimumDistance is replaced with 2. This means the default Levenshtein threshold used by this path is two edits or fewer, unless the command changes the threshold.
SuggestionsFor examines only commands for which IsAvailableCommand is true. For each one, it computes case-insensitive Levenshtein distance, accepts the command when that distance is within SuggestionsMinimumDistance, and also accepts a case-insensitive prefix match. A command can additionally opt into an exact explicit trigger through its SuggestFor entries, which are compared with strings.EqualFold.
The distance calculation is the standard dynamic-programming matrix in ld; when ignoreCase is true, both strings are lowercased before comparison. Thus a typo such as servr can suggest server when the available command is within the configured distance, while a typed prefix can qualify even without satisfying the distance test.
The resulting text is not generated as a literal quoted sentence such as did you mean 'server'?. Instead, findSuggestions formats a block beginning with Did you mean this? and lists each suggestion on its own line. The unknown-command error embeds that block after the command path.
This workflow shows where the typo travels and where the candidate decision is made.
Evidence
- input-argscommand.go:757
- command-findercommand.go:757
- legacy-checkargs.go:28
- suggestion-buildercommand.go:781
- candidate-scancommand.go:863
- distance-checkcobra.go:192
Sources: command.go:757-779, args.go:28-38, command.go:781-796, command.go:863-881, command.go:54-260, cobra.go:192-223
How lookup errors are reported
ExecuteC always executes from the root command: calling it on a child redirects to Root().ExecuteC(). It initializes default help and completion commands, then chooses Traverse or Find depending on TraverseChildren. In the ordinary lookup path, Find returns the command reached and any lookup error.
If lookup returns an error, ExecuteC uses the reached command when one exists, then—unless SilenceErrors is set—prints the error prefix and error text followed by Run '<command path> --help' for usage.. It returns the same error to the caller. ErrPrefix inherits from a parent when unset and otherwise defaults to Error:. CommandPath builds the displayed path by walking parents and joining command names.
This is why SilenceErrors does not mean “ignore errors”: it suppresses Cobra’s automatic lookup-error output, but the error still returns from ExecuteC and therefore from Execute. Use it when the surrounding application owns error formatting or logging.
Sources: command.go:1084-1170, command.go:757-779, command.go:643-652, command.go:1465-1470, command.go:1070-1073
How execution errors become output and exit status
After successful lookup, ExecuteC calls the selected command’s execute method. execute parses flags first and routes flag-parse failures through FlagErrorFunc; it then handles help and version requests, checks that the command is runnable, validates positional arguments, runs hooks, and invokes the command’s execution callbacks, including RunE. A RunE implementation is specifically the error-returning form of Run.
When execute returns an error, ExecuteC gives help errors special treatment: flag.ErrHelp invokes HelpFunc and returns success. Other errors are printed to the command’s error writer unless either the command or root has SilenceErrors set. The error writer comes from ErrOrStderr, which resolves an explicitly configured writer, inherits through parents, or falls back to standard error.
For ordinary execution failures, ExecuteC separately checks SilenceUsage; when usage is not silenced, it prints UsageString() after the error. UsageString temporarily directs both output writers to a buffer, runs Usage, restores the writers, and returns the buffer contents. The usage function renders through the configured usage template or the default usage function.
The two silence controls therefore have different purposes: set SilenceErrors when the caller will report the returned error, set SilenceUsage when usage would be unwanted noise for execution failures, and set both when the caller wants complete control over reporting. The shown execution path still returns the error in all of these cases.
If the application wants a process exit code, it must perform that conversion. Calling CheckErr(err) prints Error: <err> to os.Stderr and exits with status 1 when the error is non-nil. Cobra’s Execute method itself only returns the error received from ExecuteC.
This sequence distinguishes Cobra’s reporting from the application’s final process decision.
Evidence
- applicationcommand.go:1070
- root-executecommand.go:1084
- command-runnercommand.go:905
- error-writercommand.go:1157
- exit-helpercobra.go:235
Sources: command.go:1084-1170, command.go:905-1045, command.go:54-260, command.go:403-405, command.go:422-430, command.go:526-542, command.go:444-460, command.go:1070-1073, cobra.go:235-240
How it connects
Command construction determines which children are available for suggestion and lookup: AddCommand assigns each child’s parent and appends it to the command list. The command tree and parent/root traversal are covered in Command Tree & Registration.
Lookup occurs inside the broader execution sequence, including flag parsing and run hooks; see Command Execution Flow. Flag failures are parsed after persistent flags are merged, as described in Flag Parsing & Persistent Flags. Usage and help output use templates and writers, covered in Help, Usage & Templates.
Sources: command.go:1342-1368, command.go:1084-1170, command.go:444-460
Key takeaways
- Suggestions consider available commands, Levenshtein distance, prefixes, and explicit
SuggestForentries. - The default suggestion distance is
2whenSuggestionsMinimumDistanceis non-positive. SilenceErrorssuppresses Cobra’s automatic error text;SilenceUsagesuppresses usage output for execution errors.Executereturns the error;CheckErris the shown helper that prints it and exits with status1.
Sources: command.go:863-881, command.go:781-796, command.go:1084-1170, command.go:1070-1073, cobra.go:235-240