slackhq/nebula · error
failed to cast command
Error message
failed to cast command
What it means
The nebula sshd stores commands in a radix tree as interface{} values. lookupCommand retrieves a value by name and asserts it is *Command; if the stored value is of any other type, it returns "failed to cast command" instead of panicking. This guards against registry entries that violate the *Command contract.
Source
Thrown at sshd/command.go:80
cmds := make([]string, 0)
for _, l := range allCommands(c) {
cmds = append(cmds, fmt.Sprintf("%s - %s", l.Name, l.ShortDescription))
}
sort.Strings(cmds)
_ = w.Write(strings.Join(cmds, "\n") + "\n\n")
}
func lookupCommand(c *radix.Tree, sCmd string) (*Command, error) {
cmd, ok := c.Get(sCmd)
if !ok {
return nil, nil
}
command, ok := cmd.(*Command)
if !ok {
return nil, errors.New("failed to cast command")
}
return command, nil
}
func matchCommand(c *radix.Tree, cmd string) []string {
cmds := make([]string, 0)
c.WalkPrefix(cmd, func(found string, v any) bool {
cmds = append(cmds, found)
return false
})
sort.Strings(cmds)
return cmds
}
func allCommands(c *radix.Tree) []*Command {
cmds := make([]*Command, 0)
c.WalkPrefix("", func(found string, v any) bool {View on GitHub (pinned to dd8f660c0a)
Solutions
- Inspect the code path that inserts commands into the sshd radix tree and ensure it always stores *Command values
- Fix the registration site so the concrete type implements/converts to *Command
- Check for multiple conflicting registrations of the same command name from different init paths
Example fix
// before
tree.Insert(name, myCommandStruct{})
// after
tree.Insert(name, &Command{
Name: name,
ShortHelp: "...",
Run: myRunFunc,
}) Defensive patterns
Strategy: type-guard
Validate before calling
if v, ok := tree.Get(name); !ok {
return nil, nil // command not found
} Type guard
command, ok := cmd.(*Command)
if !ok {
return nil, errors.New("failed to cast command")
} Try / catch
command, err := lookupCommand(tree, name)
if err != nil {
l.WithError(err).WithField("name", name).Error("command lookup failed")
return err
} Prevention
- Only insert *Command values into the sshd radix tree
- Centralize command registration in one function
- Add a startup assertion that walks the tree asserting all values are *Command
- Review refactors that change the stored command type
When it happens
Trigger: A value registered into the sshd command radix tree (e.g., via tree.Insert) that is not a *Command is looked up by lookupCommand, so the `cmd.(*Command)` type assertion fails.
Common situations: Custom sshd command registration code inserting the wrong concrete type; refactors that change the command type stored in the tree; test code registering stubs into the command tree.
Related errors
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/caa61c286009da62.
Report an issue: GitHub.