kovidgoyal/kitty · error · ValueError

Ignoring invalid menu action: {val}

Error message

Ignoring invalid menu action: {val}

What it means

menu_map parses menu directives in kitty.conf; it splits the value into two parts (menu type and the rest). If there is no second part (only one token), this ValueError is raised, meaning the menu action is malformed.

Source

Thrown at kitty/options/utils.py:1149

            key, v = key.strip(), v.strip()
            if key:
                if v:
                    v = expandvars(v, current_val)
                yield key, v
        else:
            yield val, DELETE_ENV_VAR


def store_multiple(val: str, current_val: Container[str]) -> Iterable[tuple[str, str]]:
    val = val.strip()
    if val not in current_val:
        yield val, val


def menu_map(val: str, current_val: Container[str]) -> Iterable[tuple[tuple[str, ...], str]]:
    parts = val.split(maxsplit=1)
    if len(parts) != 2:
        raise ValueError(f'Ignoring invalid menu action: {val}')
    if parts[0] != 'global':
        raise ValueError(f'Unknown menu type: {parts[0]}. Known types: global')
    start = 0
    if parts[1].startswith('"'):
        start = 1
        idx = parts[1].find('"', 1)
        if idx == -1:
            raise ValueError(f'The menu entry name in {val} must end with a double quote')
    else:
        idx = parts[1].find(' ')
        if idx == -1:
            raise ValueError(f'The menu entry {val} must have an action')
    location = ('global',) + tuple(parts[1][start:idx].split('::'))
    yield location, parts[1][idx + 1 :].lstrip()


allowed_shell_integration_values = frozenset({'enabled', 'disabled', 'no-rc', 'no-cursor', 'no-title', 'no-prompt-mark', 'no-complete', 'no-cwd', 'no-sudo'})

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Write the full form: menu global <name-path> <action>
  2. See the menus kitten documentation for exact syntax

Example fix

# before
menu global
# after
menu global "My Menu::Item" launch --type=tab nvim
Defensive patterns

Strategy: validation

Validate before calling

def valid_menu_line(val: str) -> bool:
    return len(val.split(maxsplit=1)) == 2

Prevention

When it happens

Trigger: menu global with no location/action after it, i.e. a single-token menu line.

Common situations: Incomplete copy-paste of menu examples from kitten docs, or missing the menu path and action.

Related errors


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