Skip to content

fix: don't suggest hidden flags or commands - #2480

Merged
Juneezee merged 2 commits into
urfave:mainfrom
INo-xious:fix/suggest-hidden-flags
Oct 20, 2026
Merged

Juneezee merged 2 commits into
urfave:mainfrom
INo-xious:fix/suggest-hidden-flags

Conversation

@INo-xious

@INo-xious INo-xious commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • bug

What this PR does / why we need it:

With Suggest: true, a mistyped flag gets a "Did you mean" hint from suggestFlag, which looks at every flag name, including flags declared Hidden: true. Hidden flags are already left out of help output and, since #2388, out of shell completion, so naming one in the usage error gives away the flag the application meant to hide:

cmd := &cli.Command{
    Name:    "app",
    Suggest: true,
    Flags: []cli.Flag{
        &cli.BoolFlag{Name: "internal-debug", Hidden: true},
        &cli.BoolFlag{Name: "verbose"},
    },
}
// app --internal-debu

On main this prints:

Incorrect Usage: flag provided but not defined: -internal-debu

Did you mean "--internal-debug"?

The GLOBAL OPTIONS section printed right after it lists only --verbose and --help.

  • suggestions.go: suggestFlag skips the names of a flag that implements VisibleFlag and reports !IsVisible(). This is the same check printFlagSuggestions uses for shell completion. The help flag names are still appended as before, so help is suggested exactly as it is today. When no visible name is close, the existing best-score fallback applies. For the example above the hint becomes Did you mean "--verbose"?.
  • suggestions_test.go: one unit test on suggestFlag and one end-to-end test through Command.Run.

suggestCommand is unchanged, because it also resolves commands for PrefixMatchCommands. The second commit filters hidden commands at the help <name> call site instead: with a hidden putz command, app help put failed with No help topic for 'put'. putz. TestCommandHelpSuggestHiddenCommand covers it.

Which issue(s) this PR fixes:

None filed.

Special notes for your reviewer:

A custom flag type that doesn't implement VisibleFlag is still suggested, which matches shell completion. All the built-in flag types implement it.

Testing

go test -run 'TestSuggestFlagHiddenFlag' ./   # both tests fail on main, pass here
go test ./...                                 # ok
go test -tags urfave_cli_no_template ./...    # ok
make vet                                      # ok
make test                                     # ok
make check-binary-size                        # ok
make v3diff                                   # ok
golangci-lint run ./...                       # 0 issues

On main, TestSuggestFlagHiddenFlag fails with expected: "--verbose", actual: "--internal-debug", and TestSuggestFlagHiddenFlagFromRun fails because the output contains Did you mean "--internal-debug"?.

No exported API or doc comments change, so godoc-current.txt is unaffected. (With Go 1.24 locally, make generate rewrites three unrelated doc-link lines in godoc-current.txt on main too. That comes from the local toolchain version, not this change.)

Release Notes

Suggestions for mistyped flags ("Did you mean ...?") and for unknown `help <command>` topics no longer offer flags or commands that are marked Hidden.

With Suggest enabled, a mistyped flag gets a "Did you mean" hint
built from every flag name, including flags declared Hidden. Hidden
flags are already left out of help output and shell completion, so
advertising them in the error output defeats the purpose of hiding
them.

Skip flags that report themselves as not visible when picking a
suggestion. The help flag names are still considered as before.
@INo-xious
INo-xious requested a review from a team as a code owner October 20, 2026 05:37

@coilysiren coilysiren left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great change!

With Suggest enabled, "app help <name>" with an unknown name appends the
closest command name to the "No help topic" error, including commands
declared Hidden. With a hidden "putz" command, "app help put" fails
with:

  No help topic for 'put'. putz

Hidden commands are already left out of help output and shell
completion, so leave them out of this suggestion too. Filter them at
this call site instead of in suggestCommand, because PrefixMatchCommands
also resolves command names through suggestCommand.

Fixes: 002bde2 ("Add suggestions support")
Assisted-by: claude:claude-opus-5-5
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
@Juneezee Juneezee changed the title fix: don't suggest hidden flags fix: don't suggest hidden flags or commands Oct 20, 2026

@Juneezee Juneezee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Confirmed on main: with Suggest: true, app --internal-debu gets Did you mean "--internal-debug"? for the hidden flag, and both new tests fail there and pass here.

help <name> had the same leak for hidden commands. With a hidden putz and a visible pull, app help put failed with No help topic for 'put'. putz. I pushed 24bab17 to filter hidden commands at that call site, so it now suggests pull:

cli/help.go

Lines 341 to 352 in 24bab17

if cmd.Suggest {
// Hidden commands must not be suggested, as in shell completion.
var commands []*Command
for _, subCmd := range cmd.Commands {
if !subCmd.Hidden {
commands = append(commands, subCmd)
}
}
if suggestion := SuggestCommand(commands, commandName); suggestion != "" {
errMsg += ". " + suggestion
}
}

suggestCommand itself stays unchanged, as you noted, because PrefixMatchCommands resolves command names through it. Filtering there would make app putz run pull:

cli/command_run.go

Lines 297 to 301 in 05d84c1

if cmd.SuggestCommandFunc != nil && name != "--" {
name = cmd.SuggestCommandFunc(cmd.Commands, name)
tracef("suggested command name=%1[q] (cmd=%[2]q)", name, cmd.Name)
}
subCmd = cmd.Command(name)

I also updated the title and the release note to cover both.

@Juneezee
Juneezee merged commit 835fca1 into urfave:main Oct 20, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants