spf13/cobra · error

unknown command %q for %q

Error message

unknown command %q for %q

What it means

Returned by the NoArgs PositionalArgs validator when the user supplies any positional arguments to a command that is configured to accept none. Unlike legacyArgs, NoArgs is opt-in — you must explicitly assign it to Command.Args. It reports the first stray argument as an 'unknown command' because a no-arg command typically only has flag and subcommand surface.

Source

Thrown at args.go:44

// - root commands with subcommands will do subcommand validity checking
// - subcommands will always accept arbitrary arguments
func legacyArgs(cmd *Command, args []string) error {
	// no subcommand, always take args
	if !cmd.HasSubCommands() {
		return nil
	}

	// root command with subcommands, do subcommand checking.
	if !cmd.HasParent() && len(args) > 0 {
		return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
	}
	return nil
}

// NoArgs returns an error if any args are included.
func NoArgs(cmd *Command, args []string) error {
	if len(args) > 0 {
		return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
	}
	return nil
}

// OnlyValidArgs returns an error if there are any positional args that are not in
// the `ValidArgs` field of `Command`
func OnlyValidArgs(cmd *Command, args []string) error {
	if len(cmd.ValidArgs) > 0 {
		// Remove any description that may be included in ValidArgs.
		// A description is following a tab character.
		validArgs := make([]string, 0, len(cmd.ValidArgs))
		for _, v := range cmd.ValidArgs {
			validArgs = append(validArgs, strings.SplitN(v, "\t", 2)[0])
		}
		for _, v := range args {
			if !stringInSlice(v, validArgs) {
				return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
			}

View on GitHub (pinned to adbc881390)

Solutions

  1. Remove the stray positional argument from the invocation.
  2. If the command should accept those args, switch to a permissive validator (ArbitraryArgs) or a counting one (ExactArgs/MaximumNArgs).
  3. If the arg was meant for a child command, fix the command path / routing.

Example fix

// before
cmd := &cobra.Command{Use: "version", Args: cobra.NoArgs}
// `version 1.2.3` -> unknown command "1.2.3"

// after: accept and ignore, or document
// (remove the arg, or) cmd.Args = cobra.ArbitraryArgs
Defensive patterns

Strategy: validation

Validate before calling

// Reject stray positionals before invoking a NoArgs command
func ensureNoArgs(args []string) error {
    if len(args) > 0 {
        return fmt.Errorf("this command takes no positional args; got %v", args)
    }
    return nil
}

Type guard

null

Try / catch

// In RunE, treat the (already-validated) args as empty by contract
RunE: func(cmd *cobra.Command, args []string) error {
    // NoArgs guaranteed args is empty; proceed without indexing args
}

Prevention

When it happens

Trigger: Assigning `Args: cobra.NoArgs` on a command and then invoking it with a positional token, e.g. `app version extra`. Also fires when a subcommand with NoArgs receives args intended for a sibling, or when shell completion logic forwards args incorrectly.

Common situations: Commands meant to be leaf/action-only (version, info, status) accidentally receiving args; arg-quoting bugs in shell wrappers; subcommands whose parent passes leftover args down.

Related errors


AI-assisted analysis of spf13/cobra@adbc881390 (2026-08-04). Data as JSON: /data/errors/afc3af6bb46720ee.json. Report an issue: GitHub.