kovidgoyal/kitty · error

Must specify exactly %s argument(s) for %s

Error message

Must specify exactly %s argument(s) for %s

What it means

Generated Go validation for RC commands with a fixed positive args_count: the handler checks len(args) against the required count and rejects mismatches, telling you exactly how many arguments the command needs.

Source

Thrown at kitty/rc/base.py:230

    def args_count(self) -> int | None:
        if not self.spec:
            return 0
        return self.count

    def as_go_completion_code(self, go_name: str) -> Iterator[str]:
        c = self.args_count
        if c is not None:
            yield f'{go_name}.StopCompletingAtArg = {c}'
        if self.completion:
            yield from self.completion.as_go_code(go_name + '.ArgCompleter', ' = ')

    def as_go_code(self, cmd_name: str, field_types: dict[str, str], handled_fields: set[str]) -> Iterator[str]:
        c = self.args_count
        if c == 0:
            yield f'if len(args) != 0 {{ return fmt.Errorf("%s", "Unknown extra argument(s) supplied to {cmd_name}") }}'
            return
        if c is not None:
            yield f'if len(args) != {c} {{ return fmt.Errorf("%s", "Must specify exactly {c} argument(s) for {cmd_name}") }}'
        if self.value_if_unspecified:
            yield 'if len(args) == 0 {'
            for x in self.value_if_unspecified:
                yield f'args = append(args, "{x}")'
            yield '}'
        if self.minimum_count > -1:
            if self.minimum_count == 1:
                yield f'if len(args) < {self.minimum_count} {{ return fmt.Errorf("%s", "Must specify at least one argument to {cmd_name}") }}'
            else:
                yield f'if len(args) < {self.minimum_count} {{ return fmt.Errorf("%s", "Must specify at least {self.minimum_count} arguments to {cmd_name}") }}'
        if self.args_choices:
            achoices = tuple(self.args_choices())
            yield 'achoices := map[string]bool{' + ' '.join(f'"{x}":true,' for x in achoices) + '}'
            yield 'for _, a := range args {'
            yield 'if !achoices[a] { return fmt.Errorf("Not a valid choice: %s. Allowed values are: %s", a, "' + ', '.join(achoices) + '") }'
            yield '}'
        if self.json_field:
            jf = self.json_field

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Supply exactly the number of positional args stated in the error message
  2. Inspect kitty @ <cmd> --help for the argument list and order
  3. In scripts, quote each argument explicitly and assert len(args) == expected before sending
  4. Pin/align kitty versions between client and server so arg schemas match

Example fix

# before
kitten @ send-text --match-tab title:mytab "hello"
# (command expected exactly N positional args, got fewer)

# after
# pass each required positional argument, properly quoted:
kitten @ send-text hello
Defensive patterns

Strategy: validation

Validate before calling

if len(args) != cmd.ArgsCount {
    return fmt.Errorf("%s needs exactly %d args, got %d", cmd.Name, cmd.ArgsCount, len(args))
}

Type guard

func hasExactArgs(args []string, n int) bool { return len(args) == n }

Try / catch

if err := runRCCommand(cmd, args); err != nil {
    if strings.Contains(err.Error(), "Must specify exactly") {
        return fmt.Errorf("%w — check kitty @ %s --help", err, cmd.Name)
    }
    return err
}

Prevention

When it happens

Trigger: Calling a remote control command with too few or too many positional args — e.g. a command requiring exactly 2 args given 1 or 3; happens via kitten @ CLI, the remote control socket JSON payload, or scripts building arg arrays dynamically.

Common situations: Unquoted shell words splitting/joining args incorrectly; commands whose arg count changed across kitty versions; programmatic RC payloads with hardcoded arg arrays drifting from the schema; empty string args being dropped.

Related errors


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