kovidgoyal/kitty · error · RemoteControlErrorWithoutTraceback

Must specify an action

Error message

Must specify an action

What it means

Thrown by the @ action remote-control command in kitty when the payload contains no 'action' field. The remote control API requires an action string (e.g. 'send_text', 'scroll_line_down', or a keymap definition) to execute; an empty payload is rejected with RemoteControlErrorWithoutTraceback, which prints the message to the remote-control client without a Python traceback.

Source

Thrown at kitty/rc/action.py:71

    )

    args = RemoteCommand.Args(
        spec='ACTION [ARGS FOR ACTION...]',
        json_field='action',
        minimum_count=1,
        completion=RemoteCommand.CompletionSpec.from_string('type:special group:complete_actions'),
    )

    def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
        return {'action': ' '.join(args), 'self': opts.self, 'match_window': opts.match}

    def response_from_kitty(self, boss: Boss, window: Window | None, payload_get: PayloadGetType) -> ResponseType:
        w = self.windows_for_match_payload(boss, window, payload_get)
        if w:
            window = w[0]
        ac = payload_get('action')
        if not ac:
            raise RemoteControlErrorWithoutTraceback('Must specify an action')

        try:
            consumed = boss.combine(str(ac), window, raise_error=True)
        except (Exception, SystemExit) as e:
            raise RemoteControlErrorWithoutTraceback(str(e))

        if not consumed:
            raise RemoteControlErrorWithoutTraceback(f'Unknown action: {ac}')
        return None


action = Action()

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Pass the action explicitly: kitten @ action --action=send_text or use the shorthand kitten @ action send_text msg Hello
  2. Check the action name is a valid kitty action (see the mappings/actions docs or 'kitten @ run --help')
  3. If scripting raw payloads, verify the 'action' key exists and is non-empty before sending

Example fix

# before
kitten @ action

# after
kitten @ action send_text all Hello
Defensive patterns

Strategy: validation

Validate before calling

ac = payload.get('action') if isinstance(payload, dict) else payload_get('action')
if not ac:
    raise SystemExit('refusing to send action rc command without an action')
subprocess.run(['kitten', '@', 'action', str(ac)], check=True)

Type guard

def has_action_payload(payload: dict) -> bool:
    return bool(payload.get('action')) and isinstance(payload['action'], str)

Try / catch

from kittens.rpc import RemoteControlErrorWithoutTraceback  # conceptually
try:
    run_action_rc(ac)
except RemoteControlErrorWithoutTraceback as e:
    print(f'action rc failed: {e}')  # message printed without traceback; handle gracefully

Prevention

When it happens

Trigger: Running 'kitten @ action' with no --action/-a argument, or constructing a raw remote-control payload (JSON or escape-code based) that omits the 'action' key.

Common situations: Shell scripts that build the command dynamically and pass an empty string, passing action args in the wrong position, or JSON payloads with a typo'd key like 'actions'.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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