{"record":{"id":"185e98f47de7d4a0","repo":"kovidgoyal/kitty","slug":"the-remote-control-password-was-invalid-data-r","errorCode":null,"errorMessage":"The remote control password was invalid: {data!r}","messagePattern":"The remote control password was invalid: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"kittens/tui/handler.py","lineNumber":84,"sourceCode":"    def initialize(self) -> None:\n        if self.initialized:\n            return\n        self.initialized = True\n        if running_in_kitty():\n            return\n        if self.allow_remote_control:\n            self.to = os.environ.get('KITTY_LISTEN_ON', '')\n            if not self.to:\n                raise ValueError('Remote control not enabled, this kitten should be run via a map in kitty.conf, not from the command line')\n            self.rc_fd = int(self.to.partition(':')[-1])\n            os.set_inheritable(self.rc_fd, False)\n        if (self.remote_control_password or self.remote_control_password == '') and not self.password:\n            import socket\n\n            with socket.fromfd(self.rc_fd, socket.AF_UNIX, socket.SOCK_STREAM) as s:\n                data = s.recv(256)\n            if not data.endswith(b'\\n'):\n                raise Exception(f'The remote control password was invalid: {data!r}')\n            self.password = data.strip().decode()\n\n    def __call__(self, args: list[str]) -> str:\n        self.initialize()\n        return self.func(args)\n\n    def allow_indiscriminate_remote_control(self, enable: bool = True) -> None:\n        if self.rc_fd > -1:\n            if enable:\n                os.set_inheritable(self.rc_fd, True)\n                if self.password:\n                    os.environ['KITTY_RC_PASSWORD'] = self.password\n            else:\n                os.set_inheritable(self.rc_fd, False)\n                if self.password:\n                    os.environ.pop('KITTY_RC_PASSWORD', None)\n\n    def remote_control(self, cmd: str | Sequence[str], **kw: Any) -> Any:","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/tui/handler.py#L66-L102","documentation":"Raised during handler initialization when remote control password negotiation fails: the kitten reads up to 256 bytes from the inherited remote-control socket and expects the response to end with a newline. If the data does not end in b'\\n' it means the peer did not send a valid password line (wrong protocol, closed socket, or garbage), so the password cannot be extracted.","triggerScenarios":"Calling a TUI handler with remote_control_password set (or empty string) and no explicit password, where the socket behind KITTY_LISTEN_ON does not deliver a newline-terminated password line — e.g. the FD points to the wrong socket, an incompatible kitty version, or the socket was already consumed/closed.","commonSituations":"Mismatched kitty versions between the running terminal and the kitten code; KITTY_LISTEN_ON pointing at another process's socket; the rc_fd inheritance broken by an intermediate wrapper (shell, sandbox, systemd unit) that closed or duplicated FDs.","solutions":["Ensure the kitten is launched by the same kitty version that provides the socket (update kitty entirely rather than mixing binaries)","Launch via a kitty.conf map so FD inheritance is guaranteed","Pass the password explicitly (set self.password) to skip socket negotiation"],"exampleFix":"# before\nhandler = ResultHandler(func, allow_remote_control=True, remote_control_password='')  # negotiates over socket\n# after\nhandler.password = os.environ['KITTY_RC_PASSWORD']  # supply directly, skip negotiation","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    handler.initialize()\nexcept Exception as e:\n    if 'remote control password was invalid' in str(e):\n        handler.password = os.environ.get('KITTY_RC_PASSWORD', '')\n    else:\n        raise","preventionTips":["Pass the password explicitly instead of negotiating over the socket","Keep kitty and kittens on the same version","Launch via kitty maps so FD inheritance is intact"],"tags":["kitty","remote-control","authentication","socket"],"backgroundTag":"authentication-handshake-failed","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}