My urfave/cli version is
v3.12.0 (9b981a04295de5121091c479f8a7a0476d2e8d38)
Checklist
Dependency Management
- My project is using Go modules.
Describe the bug
Single-rune Unicode flag names are handled inconsistently. Shell completion counts runes and emits a single-dash flag such as -ש, but help formatting counts bytes and displays --ש. More importantly, the parser examines rune(firstArg[1]), which converts only the first UTF-8 byte rather than decoding the first rune.
For ש, the first byte is 0xD7; converting that byte to a rune produces ×, which is not a letter. The parser therefore classifies -ש as a positional argument and never sets the registered flag.
To reproduce
package main
import (
"context"
"fmt"
"github.com/urfave/cli/v3"
)
func main() {
const name = "ש"
cmd := &cli.Command{
Name: "app",
Flags: []cli.Flag{&cli.StringFlag{Name: name}},
Action: func(_ context.Context, cmd *cli.Command) error {
fmt.Printf("value=%q args=%q\n", cmd.String(name), cmd.Args().Slice())
return nil
},
}
_ = cmd.Run(context.Background(), []string{"app", "-" + name, "value", "operand"})
}
Observed behavior
value="" args=["-ש" "value" "operand"]
Help formatting also prefixes this single-rune name with --, while flag completion uses -.
Expected behavior
A one-rune Unicode flag should be treated consistently with a one-byte ASCII flag:
value="value" args=["operand"]
Help and completion should both render it as -ש.
Additional context
prefixFor uses len(name) == 1, while completion already uses utf8.RuneCountInString. In parseFlags, decoding the first rune after the leading dash instead of converting firstArg[1] would preserve existing ASCII behavior and correctly classify Unicode letters.
Want to fix this yourself?
Yes. The fix is small and can be covered by a focused regression test.
Run go version and paste its output here
go version go1.26.5 windows/amd64
Relevant go env output
GOOS=windows
GOARCH=amd64
GOVERSION=go1.26.5
CGO_ENABLED=0
My urfave/cli version is
v3.12.0 (
9b981a04295de5121091c479f8a7a0476d2e8d38)Checklist
Dependency Management
Describe the bug
Single-rune Unicode flag names are handled inconsistently. Shell completion counts runes and emits a single-dash flag such as
-ש, but help formatting counts bytes and displays--ש. More importantly, the parser examinesrune(firstArg[1]), which converts only the first UTF-8 byte rather than decoding the first rune.For
ש, the first byte is0xD7; converting that byte to a rune produces×, which is not a letter. The parser therefore classifies-שas a positional argument and never sets the registered flag.To reproduce
Observed behavior
Help formatting also prefixes this single-rune name with
--, while flag completion uses-.Expected behavior
A one-rune Unicode flag should be treated consistently with a one-byte ASCII flag:
Help and completion should both render it as
-ש.Additional context
prefixForuseslen(name) == 1, while completion already usesutf8.RuneCountInString. InparseFlags, decoding the first rune after the leading dash instead of convertingfirstArg[1]would preserve existing ASCII behavior and correctly classify Unicode letters.Want to fix this yourself?
Yes. The fix is small and can be covered by a focused regression test.
Run
go versionand paste its output hereRelevant
go envoutput