{"record":{"id":"5d76d0924c68cb05","repo":"kovidgoyal/kitty","slug":"ignoring-invalid-menu-action-val","errorCode":null,"errorMessage":"Ignoring invalid menu action: {val}","messagePattern":"Ignoring invalid menu action: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kitty/options/utils.py","lineNumber":1149,"sourceCode":"            key, v = key.strip(), v.strip()\n            if key:\n                if v:\n                    v = expandvars(v, current_val)\n                yield key, v\n        else:\n            yield val, DELETE_ENV_VAR\n\n\ndef store_multiple(val: str, current_val: Container[str]) -> Iterable[tuple[str, str]]:\n    val = val.strip()\n    if val not in current_val:\n        yield val, val\n\n\ndef menu_map(val: str, current_val: Container[str]) -> Iterable[tuple[tuple[str, ...], str]]:\n    parts = val.split(maxsplit=1)\n    if len(parts) != 2:\n        raise ValueError(f'Ignoring invalid menu action: {val}')\n    if parts[0] != 'global':\n        raise ValueError(f'Unknown menu type: {parts[0]}. Known types: global')\n    start = 0\n    if parts[1].startswith('\"'):\n        start = 1\n        idx = parts[1].find('\"', 1)\n        if idx == -1:\n            raise ValueError(f'The menu entry name in {val} must end with a double quote')\n    else:\n        idx = parts[1].find(' ')\n        if idx == -1:\n            raise ValueError(f'The menu entry {val} must have an action')\n    location = ('global',) + tuple(parts[1][start:idx].split('::'))\n    yield location, parts[1][idx + 1 :].lstrip()\n\n\nallowed_shell_integration_values = frozenset({'enabled', 'disabled', 'no-rc', 'no-cursor', 'no-title', 'no-prompt-mark', 'no-complete', 'no-cwd', 'no-sudo'})\n","sourceCodeStart":1131,"sourceCodeEnd":1167,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/options/utils.py#L1131-L1167","documentation":"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.","triggerScenarios":"menu global with no location/action after it, i.e. a single-token menu line.","commonSituations":"Incomplete copy-paste of menu examples from kitten docs, or missing the menu path and action.","solutions":["Write the full form: menu global <name-path> <action>","See the menus kitten documentation for exact syntax"],"exampleFix":"# before\nmenu global\n# after\nmenu global \"My Menu::Item\" launch --type=tab nvim","handlingStrategy":"validation","validationCode":"def valid_menu_line(val: str) -> bool:\n    return len(val.split(maxsplit=1)) == 2","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Template menu lines as: menu global <name> <action>"],"tags":["kitty","config","menus"],"backgroundTag":"config-value-validation-failed","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}