kovidgoyal/kitty · error · ValueError

The menu entry name in {val} must end with a double quote

Error message

The menu entry name in {val} must end with a double quote

What it means

When a menu entry name is quoted (starts with '"'), menu_map requires a matching closing double quote; if none is found in the remaining string this ValueError is raised.

Source

Thrown at kitty/options/utils.py:1157

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'})


def shell_integration(x: str) -> frozenset[str]:
    q = frozenset(x.lower().split())
    if not q.issubset(allowed_shell_integration_values):
        log_error(f'Invalid shell integration options: {q - allowed_shell_integration_values}, ignoring')
        return q & allowed_shell_integration_values or frozenset({'invalid'})
    return q

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Close the quoted name: menu global "My Item" launch nvim
  2. Alternatively omit quotes if the name has no spaces

Example fix

# before
menu global "My Item launch nvim
# after
menu global "My Item" launch nvim
Defensive patterns

Strategy: validation

Validate before calling

def valid_menu_name(rest: str) -> bool:
    if rest.startswith('"'):
        return rest.find('"', 1) != -1
    return ' ' in rest

Prevention

When it happens

Trigger: menu global "My Item launch nvim — opening quote with no closing quote before the action.

Common situations: Unbalanced quotes when menu names contain spaces; smart-quote substitution from rich-text paste.

Related errors


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