{"record":{"id":"abd1c128e77058dc","repo":"kovidgoyal/kitty","slug":"second-is-not-a-valid-pointer-shape-name","errorCode":null,"errorMessage":"{second} is not a valid pointer shape name","messagePattern":"(.+?) is not a valid pointer shape name","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"kitty/options/utils.py","lineNumber":1847,"sourceCode":"    'zoom-out',\n    'alias',\n    'copy',\n    'not-allowed',\n    'no-drop',\n    'grab',\n    'grabbing',\n    # end pointer shape names\n)\n\n\ndef pointer_shape_when_dragging(spec: str) -> tuple[str, str]:\n    parts = spec.split(maxsplit=1)\n    first = parts[0]\n    if first not in pointer_shape_names:\n        raise ValueError(f'{first} is not a valid pointer shape name')\n    second = parts[1] if len(parts) > 1 else first\n    if second not in pointer_shape_names:\n        raise ValueError(f'{second} is not a valid pointer shape name')\n    return first, second\n\n\ndef transparent_background_colors(spec: str) -> tuple[tuple[Color, float], ...]:\n    if not spec:\n        return ()\n    ans: list[tuple[Color, float]] = []\n    seen: dict[Color, int] = {}\n    for part in spec.split():\n        col, sep, alpha = part.partition('@')\n        c = to_color(col)\n        o = max(-1, min(float(alpha) if alpha else -1, 1))\n        if (idx := seen.get(c)) is not None:\n            ans[idx] = c, o\n            continue\n        seen[c] = len(ans)\n        ans.append((c, o))\n    return tuple(ans[:7])","sourceCodeStart":1829,"sourceCodeEnd":1865,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/options/utils.py#L1829-L1865","documentation":"Raised by kitty's pointer_shape parser when the pointer shape specification contains a token that is not one of the recognized pointer shape names (e.g. arrow, beam, hand). The option expects 'default_shape' or a 'text_shape default_shape' pair; the second token defaults to the first but must itself be a valid shape name. It is thrown while parsing the pointer_shape setting in kitty.conf.","triggerScenarios":"Setting pointer_shape to a misspelled or unsupported name in kitty.conf, e.g. 'pointer_shape crosshair' or 'pointer_shape beam arrows' (misspelled plural). Any value not in the pointer_shape_names set on either position triggers it.","commonSituations":"Typos in kitty.conf after upgrading (supported shape names changed across versions), copy-pasting configs from other terminals that use different cursor names, or assuming X11 cursor names (like 'xterm') work here.","solutions":["Use a valid shape name: one of arrow, beam, hand (check pointer_shape_names in kitty/options/utils.py for the authoritative list)","If specifying two shapes ('text default'), verify both tokens individually","Remove the option to fall back to the default (arrow)"],"exampleFix":"# before\npointer_shape crosshair\npointer_shape text beam default\n\n# after\npointer_shape hand\npointer_shape beam hand","handlingStrategy":"validation","validationCode":"from kitty.options.utils import pointer_shape_names  # or hardcode: {'arrow','beam','hand'}\nvalid = {'arrow', 'beam', 'hand'}\nshapes = spec.split()\nassert all(s in valid for s in shapes[:2]), f'invalid pointer shape in {spec!r}'","typeGuard":"def is_pointer_shape_spec(spec: str) -> bool:\n    names = {'arrow', 'beam', 'hand'}\n    parts = spec.split()\n    return 1 <= len(parts) <= 2 and all(p in names for p in parts)","tryCatchPattern":null,"preventionTips":["Validate shape names against the documented set before writing kitty.conf","Reload config in a test kitty instance before deploying ('kitten @ load-config') to catch parse errors early"],"tags":["kitty","config","pointer","cursor","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}