kovidgoyal/kitty · error · KeyError

Unknown kitty remote control command: {cmd_name}

Error message

Unknown kitty remote control command: {cmd_name}

What it means

KeyError raised by kitty's remote-control command loader when 'kitty.rc.<name>' cannot be imported — i.e. the requested rc subcommand name is not a known remote-control command. Hyphens are normalized to underscores before the module lookup, so both 'goto-layout' and 'goto_layout' resolve the same way; failure means no such module exists.

Source

Thrown at kitty/rc/base.py:469

        if command.args.args_count == 0:
            raise SystemExit(f'Unknown extra argument(s) supplied to {command.name}')
        raise SystemExit(f'Must specify exactly {command.args.args_count} argument(s) for {command.name}')
    return opts, items


def display_subcommand_help(func: RemoteCommand) -> None:
    with suppress(SystemExit):
        parse_args(['--help'], (func.options_spec or '\n').format, func.args.spec, func.desc, func.name)


def command_for_name(cmd_name: str) -> RemoteCommand:
    from importlib import import_module

    cmd_name = cmd_name.replace('-', '_')
    try:
        m = import_module(f'kitty.rc.{cmd_name}')
    except ImportError:
        raise KeyError(f'Unknown kitty remote control command: {cmd_name}')
    return cast(RemoteCommand, getattr(m, cmd_name))


def all_command_names() -> frozenset[str]:

    def ok(name: str) -> bool:
        root, _, ext = name.rpartition('.')
        return bool(ext in ('py', 'pyc', 'pyo') and root and root not in ('base', '__init__'))

    return frozenset({x.rpartition('.')[0] for x in filter(ok, list_kitty_resources('kitty.rc'))})

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. List valid commands with 'kitten @' or via all_command_names() / the remote-control docs
  2. Fix the spelling; use hyphens or underscores consistently
  3. If the command was removed in an upgrade, check the changelog for its replacement

Example fix

# before
kitten @ goto_layout l1

# after
kitten @ goto-layout l1   # and verify name via: kitten @ ls of docs; 'kitten @' with no args lists commands
Defensive patterns

Strategy: validation

Validate before calling

from kitty.rc.base import all_command_names
name = 'goto-layout'
if name.replace('_','-') not in {n.replace('_','-') for n in all_command_names()}:
    raise ValueError(f'{name} is not a kitty rc command')

Type guard

def is_rc_command(cmd: str) -> bool:
    return cmd.replace('-', '_') in {c.replace('-', '_') for c in all_command_names()}

Try / catch

from kitty.rc.base import command_for_name
try:
    command_for_name(cmd_name)
except KeyError:
    log.warning('unknown rc command %s; available: %s', cmd_name, sorted(all_command_names()))
    return None  # skip or prompt user

Prevention

When it happens

Trigger: Calling 'kitten @ nosuchcmd', command_for_name('foo'), or listing an invalid command in --remote-control-command allowlists/tooling that introspects commands.

Common situations: Typos in command names, commands removed/renamed between kitty versions (e.g. older aliases), or custom kittens expected to appear as @ commands without proper registration.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/f15b8b3c35d48aaf. Report an issue: GitHub.