{"record":{"id":"348dfd108baac55c","repo":"kovidgoyal/kitty","slug":"native-key-codes-not-allowed-in-send-key-human-k","errorCode":null,"errorMessage":"Native key codes not allowed in send_key: {human_key}","messagePattern":"Native key codes not allowed in send_key: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kitty/window.py","lineNumber":1247,"sourceCode":"        Note that the key will be sent only if the current keyboard mode of the program running in the terminal supports it.\n        Both key press and key release are sent. First presses for all specified keys and then releases in reverse order.\n        To send a pattern of press and release for multiple keys use the :ac:`combine` action. For example::\n\n            map f1 send_key ctrl+x alt+y\n            map f1 combine : send_key ctrl+x : send_key alt+y\n    \"\"\",\n    )\n    def send_key(self, *args: str) -> bool:\n        from .options.utils import parse_shortcut\n\n        km = get_options().kitty_mod\n        passthrough = True\n        events = []\n        prev = ''\n        for human_key in args:\n            sk = parse_shortcut(human_key)\n            if sk.is_native:\n                raise ValueError(f'Native key codes not allowed in send_key: {human_key}')\n            sk = sk.resolve_kitty_mod(km)\n            events.append(KeyEvent(key=sk.key, mods=sk.mods, action=GLFW_REPEAT if human_key == prev else GLFW_PRESS))\n            prev = human_key\n        scroll_needed = False\n        for ev in events + [KeyEvent(key=x.key, mods=x.mods, action=GLFW_RELEASE) for x in reversed(events)]:\n            enc = self.encoded_key(ev)\n            if enc:\n                self.write_to_child(enc)\n                if ev.action != GLFW_RELEASE and not is_modifier_key(ev.key):\n                    scroll_needed = True\n                passthrough = False\n        if scroll_needed:\n            self.scroll_end()\n        return passthrough\n\n    def send_key_sequence(self, *keys: KeyEvent, synthesize_release_events: bool = True) -> None:\n        for key in keys:\n            enc = self.encoded_key(key)","sourceCodeStart":1229,"sourceCodeEnd":1265,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/window.py#L1229-L1265","documentation":"Window.send_key() parses each human-readable key with parse_shortcut() and refuses shortcuts whose key is a native key code (sk.is_native). send_key synthesizes GLFW key events, so platform-native codes cannot be mapped; use symbolic key names instead. The check happens per argument before any events are queued.","triggerScenarios":"Calling send_key('native:0x20') or any shortcut string whose key part resolves to a native code rather than a GLFW/symbolic name, e.g. send_key('native_key_here').","commonSituations":"Feeding platform scan codes or keysym numbers obtained from other tools into send_key; remote-control scripts (kitten @ send-key) passing machine-level codes; confusing send_key with the escape-code based send_text.","solutions":["Use symbolic names: send_key('ctrl+c'), send_key('enter'), send_key('f1')","If you only need text input, use send_text / @ send-text which doesn't parse keys","Find valid names via kitten show-key"],"exampleFix":"# before\nwindow.send_key('native:65')\n# after\nwindow.send_key('space')","handlingStrategy":"validation","validationCode":"from kitty.key_encoding import parse_shortcut\nsk = parse_shortcut(human_key)\nif sk.is_native:\n    raise ValueError(f'use a symbolic key name, not {human_key}')","typeGuard":"def is_symbolic_key(human_key: str) -> bool:\n    from kitty.key_encoding import parse_shortcut\n    return not parse_shortcut(human_key).is_native","tryCatchPattern":"try:\n    window.send_key(*keys)\nexcept ValueError as e:\n    if 'Native key codes' in str(e):\n        window.send_text(' '.join(keys))  # fallback: text input\n    else:\n        raise","preventionTips":["Whitelist symbolic key names in remote-control scripts","Use send_text for literal text and send_key only for named keys/symbols"],"tags":["send-key","input-synthesis","native-key-codes"],"backgroundTag":"invalid-key-specifier","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}