Problem class: go-config-feature-loaded-but-never-dispatched-alias-class
I built a faithful minimal reproduction of the muster layout (cobra + YAML config, internal/builtin/root.go), confirmed the buggy line reproduces unknown command "ls", then verified the fix. The full solution is written to ~/alias-dispatch-fix.md and reproduced below.
aliases: parsed but never dispatched (openapi-cli <alias> → unknown command)Problem class: go-config-feature-loaded-but-never-dispatched-alias-class
Repo: github.com/wojons/muster · Commit: ad42238b
Fix files: internal/builtin/, pkg/protocol/, docs/guides/
A config file containing an aliases: block parses cleanly and is documented, but invoking an alias fails:
$ cat openapi-cli.yaml
aliases:
ls: list
$ openapi-cli ls
error: unknown command "ls" for "openapi-cli"
$ echo $?
1
The aliases block was loaded but never consumed. The data flow was:
config.Load(path) ──► cfg.Aliases = {"ls": "list"} ✅ parsed
│
▼
builtin.NewRootCmd(cfg) ──► cobra tree ✅ constructed
│
▼
root.SetArgs(os.Args[1:]) ──► cobra dispatch ❌ "ls" never rewritten
│
▼
root.ExecuteContext(ctx) ──► unknown command "ls" ❌ exit 1
Cobra only knows about commands registered via AddCommand. A value that lives solely inside cfg.Aliases is invisible to the dispatcher. There was no step between loading config and executing the command that turned the user-typed token into a real command name, so a valid config key behaved exactly like a typo'd key. "Loaded but not dispatched" is indistinguishable from "not supported".
The missing piece is an argv-rewriting dispatch step performed before ExecuteContext (and therefore before Cobra parses arguments).
Rewrite argv[1] through cfg.Aliases at command-construction time, just before SetArgs.
internal/builtin/root.go// NewRootCmd builds the root command. rawArgs is os.Args[1:] (program name
// already stripped). Aliases are resolved here so every entry point — the
// real binary and tests — gets identical dispatch semantics.
func NewRootCmd(cfg *config.Config, rawArgs []string) *cobra.Command {
root := &cobra.Command{
Use: "openapi-cli",
Short: "OpenAPI CLI",
SilenceUsage: true,
SilenceErrors: true,
}
root.AddCommand(newListCmd())
root.AddCommand(newStatusCmd())
// THE MISSING STEP: rewrite argv[1] from the config alias map before
// Cobra parses it.
root.SetArgs(ResolveAliases(root, rawArgs, cfg.Aliases))
return root
}
// ResolveAliases rewrites argv[1] through the configured alias table.
// - flags (`--help`) pass through untouched;
// - real commands (and registered cobra aliases) win over config aliases, so
// a stale alias can never shadow a built-in;
// - unknown tokens pass through and still produce a normal unknown-command
// error (a typo stays a typo).
func ResolveAliases(root *cobra.Command, rawArgs []string, aliases map[string]string) []string {
if len(rawArgs) == 0 || len(aliases) == 0 {
return rawArgs
}
first := rawArgs[0]
if len(first) > 0 && first[0] == '-' {
return rawArgs
}
if isKnownCommand(root, first) {
return rawArgs
}
target, ok := aliases[first]
if !ok || target == "" {
return rawArgs
}
out := make([]string, len(rawArgs))
copy(out, rawArgs)
out[0] = target
return out
}
func isKnownCommand(root *cobra.Command, name string) bool {
for _, c := range root.Commands() {
if c.Name() == name || c.HasAlias(name) {
return true
}
}
return false
}
// Execute is the single production entry point.
func Execute(ctx context.Context, cfg *config.Config, rawArgs []string) error {
root := NewRootCmd(cfg, rawArgs)
return root.ExecuteContext(ctx)
}
cmd/openapi-cli/main.gofunc main() {
cfgPath := os.Getenv("OPENAPI_CLI_CONFIG")
if cfgPath == "" {
cfgPath = "openapi-cli.yaml"
}
cfg, err := config.Load(cfgPath)
if err != nil {
cfg = &config.Config{Aliases: map[string]string{}}
}
if err := builtin.Execute(context.Background(), cfg, os.Args[1:]); err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
}
If the existing
NewRootCmdsignature must stay unchanged, do the rewrite at the call site instead — still beforeExecuteContext:
go root := builtin.NewRootCmd(cfg) root.SetArgs(builtin.ResolveAliases(root, os.Args[1:], cfg.Aliases)) if err := root.ExecuteContext(ctx); err != nil { ... }
docs/guides/: state explicitly that aliases are resolved before Cobra dispatch, that real commands take precedence, and that unknown aliases still fail. A documented config key must describe a code path that actually runs.pkg/protocol/: if the command catalog is exposed to clients, surface the resolved alias map (or the expanded command) so remote callers see the same names the local CLI accepts.Every config-driven behaviour needs a regression test that starts from a config file on disk. Hand-constructing a
*Configstruct in a test skips the loader and hides "loaded but not dispatched" bugs.
internal/builtin/root_test.go)func writeConfig(t *testing.T, body string) *config.Config {
t.Helper()
path := filepath.Join(t.TempDir(), "openapi-cli.yaml")
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
t.Fatalf("write config: %v", err)
}
cfg, err := config.Load(path) // really read the file from disk
if err != nil {
t.Fatalf("load config: %v", err)
}
return cfg
}
func run(t *testing.T, cfg *config.Config, args ...string) (string, error) {
t.Helper()
root := NewRootCmd(cfg, args)
var out bytes.Buffer
root.SetOut(&out)
root.SetErr(&out)
return out.String(), root.ExecuteContext(context.Background())
}
func TestAliasDispatchFromConfigFile(t *testing.T) {
cfg := writeConfig(t, "aliases:\n ls: list\n st: status\n")
out, err := run(t, cfg, "ls")
if err != nil {
t.Fatalf("alias `ls`: unexpected error: %v", err)
}
if !strings.Contains(out, "list: ok") {
t.Fatalf("alias `ls` did not dispatch to list; output=%q", out)
}
// ... same for "st" -> "status"
}
The suite also covers: extra args forwarded, a real command not being shadowed by an alias, unknown commands still failing, and an empty config file.
Restore the buggy line (root.SetArgs(rawArgs) with no alias resolution) and run:
$ go test ./internal/builtin/
--- FAIL: TestAliasDispatchFromConfigFile (0.00s)
root_test.go:47: alias `ls`: unexpected error: unknown command "ls" for "openapi-cli"
Did you mean this?
list
--- FAIL: TestAliasForwardsExtraArgs (0.00s)
root_test.go:67: unexpected error: unknown command "ls" for "openapi-cli"
FAIL
With the fix applied:
$ go test ./...
ok github.com/wojons/muster/internal/builtin 0.004s
$ go build -o /tmp/openapi-cli ./cmd/openapi-cli
$ printf 'aliases:\n ls: list\n st: status\n' > /tmp/openapi-cli.yaml
$ /tmp/openapi-cli ls # -> list: ok exit 0
$ /tmp/openapi-cli st # -> status: ok exit 0
$ /tmp/openapi-cli list # -> list: ok exit 0
$ /tmp/openapi-cli bogus
error: unknown command "bogus" for "openapi-cli"
# exit 1 (typos still fail)
openapi-cli <alias> dispatches to the mapped command, exit 0.ExecuteContext.1.What I actually ran: built the module at /tmp/muster (cobra v1.10.2 + gopkg.in/yaml.v3). With the fix: go test ./... → ok .../internal/builtin. Reverting to SetArgs(rawArgs) → the two alias tests fail with exactly unknown command "ls". The compiled binary with an on-disk openapi-cli.yaml returned exit 0/list: ok for ls, and exit 1 for bogus.
# Evidence - Problem class: go-config-feature-loaded-but-never-dispatched-alias-class - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-25T19:18:34.135Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Symptom: config aliases: block parsed fine, docs documented it, but `openapi-cli <alias>` -> unknown command exit 1. Root cause: no dispatch step ever rewrote argv \u2014 the config key was loaded but never consumed; a config key only the loader knows about is indistinguishable from a typo'd key. Fix: internal/builtin/root.go rewrites argv[1] from the aliases map at command construction (SetArgs before ExecuteContext). Rule: every config-driven behaviour needs a regression test that starts from a config file on disk.", "environment": "linux host, go 1.26.6", "language": "go", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-config-feature-loaded-but-never-dispatched-alias-class", "provider": "openrouter", "solved_at": "2026-09-25T19:18:34.135Z", "version": ""}I built a faithful minimal reproduction of the muster layout (cobra + YAML config, internal/builtin/root.go), confirmed the buggy line reproduces unknown command "ls", then verified the fix. The full solution is written to ~/alias-dispatch-fix.md and reproduced below.
aliases: parsed but never dispatched (openapi-cli <alias> → unknown command)Problem class: go-config-feature-loaded-but-never-dispatched-alias-class
Repo: github.com/wojons/muster · Commit: ad42238b
Fix files: internal/builtin/, pkg/protocol/, docs/guides/
A config file containing an aliases: block parses cleanly and is documented, but invoking an alias fails:
$ cat openapi-cli.yaml
aliases:
ls: list
$ openapi-cli ls
error: unknown command "ls" for "openapi-cli"
$ echo $?
1
The aliases block was loaded but never consumed. The data flow was:
config.Load(path) ──► cfg.Aliases = {"ls": "list"} ✅ parsed
│
▼
builtin.NewRootCmd(cfg) ──► cobra tree ✅ constructed
│
▼
root.SetArgs(os.Args[1:]) ──► cobra dispatch ❌ "ls" never rewritten
│
▼
root.ExecuteContext(ctx) ──► unknown command "ls" ❌ exit 1
Cobra only knows about commands registered via AddCommand. A value that lives solely inside cfg.Aliases is invisible to the dispatcher. There was no step between loading config and executing the command that turned the user-typed token into a real command name, so a valid config key behaved exactly like a typo'd key. "Loaded but not dispatched" is indistinguishable from "not supported".
The missing piece is an argv-rewriting dispatch step performed before ExecuteContext (and therefore before Cobra parses arguments).
Rewrite argv[1] through cfg.Aliases at command-construction time, just before SetArgs.
internal/builtin/root.go// NewRootCmd builds the root command. rawArgs is os.Args[1:] (program name
// already stripped). Aliases are resolved here so every entry point — the
// real binary and tests — gets identical dispatch semantics.
func NewRootCmd(cfg *config.Config, rawArgs []string) *cobra.Command {
root := &cobra.Command{
Use: "openapi-cli",
Short: "OpenAPI CLI",
SilenceUsage: true,
SilenceErrors: true,
}
root.AddCommand(newListCmd())
root.AddCommand(newStatusCmd())
// THE MISSING STEP: rewrite argv[1] from the config alias map before
// Cobra parses it.
root.SetArgs(ResolveAliases(root, rawArgs, cfg.Aliases))
return root
}
// ResolveAliases rewrites argv[1] through the configured alias table.
// - flags (`--help`) pass through untouched;
// - real commands (and registered cobra aliases) win over config aliases, so
// a stale alias can never shadow a built-in;
// - unknown tokens pass through and still produce a normal unknown-command
// error (a typo stays a typo).
func ResolveAliases(root *cobra.Command, rawArgs []string, aliases map[string]string) []string {
if len(rawArgs) == 0 || len(aliases) == 0 {
return rawArgs
}
first := rawArgs[0]
if len(first) > 0 && first[0] == '-' {
return rawArgs
}
if isKnownCommand(root, first) {
return rawArgs
}
target, ok := aliases[first]
if !ok || target == "" {
return rawArgs
}
out := make([]string, len(rawArgs))
copy(out, rawArgs)
out[0] = target
return out
}
func isKnownCommand(root *cobra.Command, name string) bool {
for _, c := range root.Commands() {
if c.Name() == name || c.HasAlias(name) {
return true
}
}
return false
}
// Execute is the single production entry point.
func Execute(ctx context.Context, cfg *config.Config, rawArgs []string) error {
root := NewRootCmd(cfg, rawArgs)
return root.ExecuteContext(ctx)
}
cmd/openapi-cli/main.gofunc main() {
cfgPath := os.Getenv("OPENAPI_CLI_CONFIG")
if cfgPath == "" {
cfgPath = "openapi-cli.yaml"
}
cfg, err := config.Load(cfgPath)
if err != nil {
cfg = &config.Config{Aliases: map[string]string{}}
}
if err := builtin.Execute(context.Background(), cfg, os.Args[1:]); err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
}
If the existing
NewRootCmdsignature must stay unchanged, do the rewrite at the call site instead — still beforeExecuteContext:
go root := builtin.NewRootCmd(cfg) root.SetArgs(builtin.ResolveAliases(root, os.Args[1:], cfg.Aliases)) if err := root.ExecuteContext(ctx); err != nil { ... }
docs/guides/: state explicitly that aliases are resolved before Cobra dispatch, that real commands take precedence, and that unknown aliases still fail. A documented config key must describe a code path that actually runs.pkg/protocol/: if the command catalog is exposed to clients, surface the resolved alias map (or the expanded command) so remote callers see the same names the local CLI accepts.Every config-driven behaviour needs a regression test that starts from a config file on disk. Hand-constructing a
*Configstruct in a test skips the loader and hides "loaded but not dispatched" bugs.
internal/builtin/root_test.go)func writeConfig(t *testing.T, body string) *config.Config {
t.Helper()
path := filepath.Join(t.TempDir(), "openapi-cli.yaml")
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
t.Fatalf("write config: %v", err)
}
cfg, err := config.Load(path) // really read the file from disk
if err != nil {
t.Fatalf("load config: %v", err)
}
return cfg
}
func run(t *testing.T, cfg *config.Config, args ...string) (string, error) {
t.Helper()
root := NewRootCmd(cfg, args)
var out bytes.Buffer
root.SetOut(&out)
root.SetErr(&out)
return out.String(), root.ExecuteContext(context.Background())
}
func TestAliasDispatchFromConfigFile(t *testing.T) {
cfg := writeConfig(t, "aliases:\n ls: list\n st: status\n")
out, err := run(t, cfg, "ls")
if err != nil {
t.Fatalf("alias `ls`: unexpected error: %v", err)
}
if !strings.Contains(out, "list: ok") {
t.Fatalf("alias `ls` did not dispatch to list; output=%q", out)
}
// ... same for "st" -> "status"
}
The suite also covers: extra args forwarded, a real command not being shadowed by an alias, unknown commands still failing, and an empty config file.
Restore the buggy line (root.SetArgs(rawArgs) with no alias resolution) and run:
$ go test ./internal/builtin/
--- FAIL: TestAliasDispatchFromConfigFile (0.00s)
root_test.go:47: alias `ls`: unexpected error: unknown command "ls" for "openapi-cli"
Did you mean this?
list
--- FAIL: TestAliasForwardsExtraArgs (0.00s)
root_test.go:67: unexpected error: unknown command "ls" for "openapi-cli"
FAIL
With the fix applied:
$ go test ./...
ok github.com/wojons/muster/internal/builtin 0.004s
$ go build -o /tmp/openapi-cli ./cmd/openapi-cli
$ printf 'aliases:\n ls: list\n st: status\n' > /tmp/openapi-cli.yaml
$ /tmp/openapi-cli ls # -> list: ok exit 0
$ /tmp/openapi-cli st # -> status: ok exit 0
$ /tmp/openapi-cli list # -> list: ok exit 0
$ /tmp/openapi-cli bogus
error: unknown command "bogus" for "openapi-cli"
# exit 1 (typos still fail)
openapi-cli <alias> dispatches to the mapped command, exit 0.ExecuteContext.1.What I actually ran: built the module at /tmp/muster (cobra v1.10.2 + gopkg.in/yaml.v3). With the fix: go test ./... → ok .../internal/builtin. Reverting to SetArgs(rawArgs) → the two alias tests fail with exactly unknown command "ls". The compiled binary with an on-disk openapi-cli.yaml returned exit 0/list: ok for ls, and exit 1 for bogus.
# Evidence - Problem class: go-config-feature-loaded-but-never-dispatched-alias-class - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-25T19:18:34.135Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Symptom: config aliases: block parsed fine, docs documented it, but `openapi-cli <alias>` -> unknown command exit 1. Root cause: no dispatch step ever rewrote argv \u2014 the config key was loaded but never consumed; a config key only the loader knows about is indistinguishable from a typo'd key. Fix: internal/builtin/root.go rewrites argv[1] from the aliases map at command construction (SetArgs before ExecuteContext). Rule: every config-driven behaviour needs a regression test that starts from a config file on disk.", "environment": "linux host, go 1.26.6", "language": "go", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-config-feature-loaded-but-never-dispatched-alias-class", "provider": "openrouter", "solved_at": "2026-09-25T19:18:34.135Z", "version": ""}