My urfave/cli version is
v3.9.1-0.20260524212652-be8b79d0c8de
Checklist
Dependency Management
- My project is using go modules.
Describe the bug
Custom shell completion still doesn't work because root.Before() is not being called. So my config struct is nil and the function which is being called to generated the completion slice panics.
To reproduce
func main() {
conf := &cfg.Config{}
cmd := &cli.Command{
Commands: []*cli.Command{
IndexShow(conf),
},
Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
if err := conf.Init(); err != nil {
if len(os.Args) > 1 {
return nil, err
} else {
fmt.Println(cmd.UsageText)
return nil, nil
}
}
log.Init(conf)
return nil, nil
},
}
}
func IndexShow(conf *cfg.Config) *cli.Command {
return &cli.Command{
Name: "show",
Aliases: []string{"sh"},
Usage: "show details about an index",
Action: func(ctx context.Context, cmd *cli.Command) error {
index := cmd.Args().Get(0)
if index == "" {
return errors.New("no index specified")
}
return es.IndexShow(conf, cmd.Args().Get(0))
},
ShellComplete: func(ctx context.Context, cmd *cli.Command) {
if cmd.NArg() > 0 {
return
}
indices, err := es.IndexNames(conf)
if err != nil {
return
}
for _, index := range indices {
fmt.Println(index)
}
},
}
}
Observed behavior
The Before() in the top level cli is not being called and the config struct is nil when shell complete is being executed. It then crashes:
./esctl index show --generate-shell-completion
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x1a5aa41]
goroutine 1 [running]:
codeberg.org/scip/esctl/pkg/es.IndexNames(0x1bf3740?)
/home/scip/dev/esctl/pkg/es/index.go:38 +0x21
codeberg.org/scip/esctl/cmd.Index.IndexShow.func2({0x1f38e6b?, 0x4?}, 0xc00022b110?)
/home/scip/dev/esctl/cmd/index.go:144 +0x34
github.com/urfave/cli/v3.checkCompletions({0x21bc5d0, 0xc000266420}, 0xc00023d8c8)
/home/scip/go/pkg/mod/github.com/urfave/cli/v3@v3.9.1-0.20260524212652-be8b79d0c8de/help.go:515 +0x24e
github.com/urfave/cli/v3.(*Command).run(0xc00023d8c8, {0x21bc5d0, 0xc000266420}, {0xc000268ed0, 0x1, 0x1})
/home/scip/go/pkg/mod/github.com/urfave/cli/v3@v3.9.1-0.20260524212652-be8b79d0c8de/command_run.go:161 +0xb7b
github.com/urfave/cli/v3.(*Command).run(0xc00023f8c8, {0x21bc5d0, 0xc000266300}, {0xc00007dd20, 0x2, 0x2})
/home/scip/go/pkg/mod/github.com/urfave/cli/v3@v3.9.1-0.20260524212652-be8b79d0c8de/command_run.go:292 +0x20b6
github.com/urfave/cli/v3.(*Command).run(0xc000245608, {0x21bc5d0, 0xc0000a1dd0}, {0xc000020100, 0x4, 0x4})
/home/scip/go/pkg/mod/github.com/urfave/cli/v3@v3.9.1-0.20260524212652-be8b79d0c8de/command_run.go:292 +0x20b6
github.com/urfave/cli/v3.(*Command).Run(...)
/home/scip/go/pkg/mod/github.com/urfave/cli/v3@v3.9.1-0.20260524212652-be8b79d0c8de/command_run.go:93
codeberg.org/scip/esctl/cmd.Main()
/home/scip/dev/esctl/cmd/root.go:119 +0x127b
main.main()
/home/scip/dev/esctl/main.go:26 +0x13
Expected behavior
I'd expect that the top level cli is being executed.
My current workaround is to load the config directly in the SHellComplete: function.
Want to fix this yourself?
We'd love to have more contributors on this project! If the fix for
this bug is easily explained and very small, feel free to create a
pull request for it.
Run go version and paste its output here
go version go1.25.0 linux/amd64
Run go env and paste its output here
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/scip/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/scip/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2427390874=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/scip/dev/esctl/go.mod'
GOMODCACHE='/home/scip/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/scip/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/scip/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.0.linux-amd64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='off'
GOTELEMETRYDIR='/home/scip/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/scip/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.0.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.0'
GOWORK=''
PKG_CONFIG='pkg-config'
My urfave/cli version is
v3.9.1-0.20260524212652-be8b79d0c8deChecklist
Dependency Management
Describe the bug
Custom shell completion still doesn't work because
root.Before()is not being called. So my config struct is nil and the function which is being called to generated the completion slice panics.To reproduce
Observed behavior
The
Before()in the top level cli is not being called and the config struct is nil when shell complete is being executed. It then crashes:Expected behavior
I'd expect that the top level cli is being executed.
My current workaround is to load the config directly in the
SHellComplete:function.Want to fix this yourself?
We'd love to have more contributors on this project! If the fix for
this bug is easily explained and very small, feel free to create a
pull request for it.
Run
go versionand paste its output hereRun
go envand paste its output here