{"record":{"id":"95b4bdb5ae6de8a2","repo":"kovidgoyal/kitty","slug":"there-was-an-error-using-a-custom-rc-auth-function","errorCode":null,"errorMessage":"There was an error using a custom RC auth function, blocking the remote command. Error: {e}","messagePattern":"There was an error using a custom RC auth function, blocking the remote command\\. Error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kitty/remote_control.py","lineNumber":163,"sourceCode":"                self.command_patterns.append(fnmatch_pattern(item))\n\n    def is_cmd_allowed(self, pcmd: dict[str, Any], window: Optional['Window'], from_socket: bool, extra_data: dict[str, Any]) -> bool:\n        cmd_name = pcmd.get('cmd')\n        if not cmd_name:\n            return False\n        if not self.function_checkers and not self.command_patterns:\n            return True\n        for x in self.command_patterns:\n            if x.match(cmd_name) is not None:\n                return True\n        for f in self.function_checkers:\n            try:\n                ret = f(pcmd, window, from_socket, extra_data)\n            except Exception as e:\n                import traceback\n\n                traceback.print_exc()\n                log_error(f'There was an error using a custom RC auth function, blocking the remote command. Error: {e}')\n                ret = False\n            if ret is not None:\n                return ret\n        return False\n\n\n@lru_cache(maxsize=256)\ndef password_authorizer(auth_items: frozenset[str]) -> PasswordAuthorizer:\n    return PasswordAuthorizer(auth_items)\n\n\nuser_password_allowed: dict[str, bool] = {}\n\n\ndef is_cmd_allowed(pcmd: dict[str, Any], window: Optional['Window'], from_socket: bool, extra_data: dict[str, Any]) -> bool | None:\n    sid = pcmd.get('stream_id', '')\n    if sid and active_streams.get(sid, '') == pcmd['cmd']:\n        return True","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/remote_control.py#L145-L181","documentation":"A custom remote-control authorization function raised an exception while vetting a command; kitty blocks the command (fail-closed) and logs the error plus a traceback.","triggerScenarios":"The user-configured is_cmd_allowed callback raises any exception during is_cmd_allowed, so ret is forced to False.","commonSituations":"Auth script bugs: KeyError on unexpected pcmd fields, attribute errors on window objects across kitty versions, or network calls in the auth function failing.","solutions":["Read the printed traceback in kitty's log to find the failing line in your auth function","Make the callback defensive: use pcmd.get(...), wrap risky checks in try/except and return explicit False","Return None (not an exception) to let other checks run, or True/False to decide"],"exampleFix":"# before\ndef is_cmd_allowed(pcmd, window, from_socket, extra_data):\n    return pcmd['cmd'] in ALLOWED\n\n# after\ndef is_cmd_allowed(pcmd, window, from_socket, extra_data):\n    return pcmd.get('cmd') in ALLOWED","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"def is_cmd_allowed(pcmd, window, from_socket, extra_data):\n    try:\n        return check(pcmd)\n    except Exception:\n        return False  # fail closed, kitty blocks the command","preventionTips":["Never assume fields exist: use pcmd.get(...)","Keep auth callbacks pure and side-effect free so they can't raise on I/O"],"tags":["kitty","remote-control","auth-callback","exception-handling"],"backgroundTag":"auth-callback-exception","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}