urfave/cli · error
flag provided but not defined: -%s
Error message
flag provided but not defined: -%s
What it means
parseFlags encountered '--name' (long form) that does not match any flag registered on the command. Unless a DefaultCommand is set (in which case unknown flags are passed through as positional args), parsing fails with 'flag provided but not defined: -<name>'.
Source
Thrown at command_parse.go:208
continue
}
// no flag lookup found and short handling is disabled
if !shortOptionHandling {
// In shell completion mode, preserve the partial flag so that DefaultCompleteWithFlags can use it
// as lastArg and offer suggestions that match the prefix.
if cmd.Root().shellCompletion {
posArgs = append(posArgs, rargs...)
return &stringSliceArgs{posArgs}, nil
}
// When DefaultCommand is set, pass unknown flags through as positional args
// so the default command can handle them (fixes #2249)
if cmd.DefaultCommand != "" {
posArgs = append(posArgs, rargs...)
return &stringSliceArgs{posArgs}, nil
}
return &stringSliceArgs{posArgs}, fmt.Errorf("%s%s", providedButNotDefinedErrMsg, flagName)
}
// try to split the flags
for index, c := range flagName {
tracef("processing flag (fName=%[1]q)", string(c))
if sf := cmd.lookupFlag(string(c)); sf == nil {
if index == 0 && cmd.DefaultCommand != "" {
posArgs = append(posArgs, rargs...)
return &stringSliceArgs{posArgs}, nil
}
return &stringSliceArgs{posArgs}, fmt.Errorf("%s%s", providedButNotDefinedErrMsg, flagName)
} else if fb, ok := sf.(boolFlag); ok && fb.IsBoolFlag() {
fv := flagVal
if index == (len(flagName)-1) && flagVal == "" {
fv = "true"
}
if fv == "" {
fv = "true"View on GitHub (pinned to 1a4deb4f5a)
Solutions
- Correct the flag spelling against the command's help output (app <cmd> --help)
- Verify the flag is declared in the Flags field of the exact command being run (flags are per-command unless persistent)
- Move the flag to the right side of the subcommand it belongs to, or declare it on root/persistent flags
Example fix
// before $ app --verbos run // after $ app run --verbose
Defensive patterns
Strategy: validation
Validate before calling
valid := map[string]bool{"verbose": true, "config": true}
for _, a := range os.Args[1:] {
if strings.HasPrefix(a, "--") {
name := strings.TrimPrefix(strings.SplitN(a, "=", 2)[0], "--")
if !valid[name] { fmt.Printf("unknown flag --%s\n", name) }
}
} Try / catch
if err := cmd.Run(os.Args); err != nil {
if strings.Contains(err.Error(), "flag provided but not defined") {
cmd := cli.Command{Name: "app"}
_ = showHelp(cmd) // surface --help with valid flags
os.Exit(2)
}
return err
} Prevention
- Run app <cmd> --help to confirm flag names before scripting
- Declare shared flags as persistent/root flags so they work on every subcommand
- Lint CI scripts after CLI version upgrades for renamed flags
When it happens
Trigger: Passing a long flag like --verbos instead of --verbose; passing a flag valid on a sibling subcommand; library version where the flag was removed or renamed.
Common situations: Typos in CI scripts; flags from an older CLI version after an upgrade; copying a command line between tools with similar but not identical flag sets.
Related errors
- no such flag -%s
- flag needs an argument: %s
- could not parse %[1]q as %[2]T value from %[3]s for flag %[4
- can't duplicate this flag
- cannot set both flags `--%s` and `--%s`
AI-assisted analysis of urfave/cli@1a4deb4f5a (2026-08-31).
Data as JSON: /api/errors/40372966df976188.
Report an issue: GitHub.