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

  1. Inspect the code path that inserts commands into the sshd radix tree and ensure it always stores *Command values
  2. Fix the registration site so the concrete type implements/converts to *Command
  3. 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

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.