{"record":{"id":"933a5d5c3c727b5c","repo":"kovidgoyal/kitty","slug":"remote-control-is-not-enabled-remember-to-use-all","errorCode":null,"errorMessage":"Remote control is not enabled, remember to use allow_remote_control=True","messagePattern":"Remote control is not enabled, remember to use allow_remote_control=True","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kittens/tui/handler.py","lineNumber":104,"sourceCode":"\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:\n        if not self.allow_remote_control:\n            raise ValueError('Remote control is not enabled, remember to use allow_remote_control=True')\n        prefix = [kitten_exe(), '@']\n        r = -1\n        pass_fds = list(kw.get('pass_fds') or [])\n        try:\n            if self.rc_fd > -1:\n                pass_fds.append(self.rc_fd)\n            if self.password and self.rc_fd > -1:\n                r, w = safe_pipe(False)\n                os.write(w, self.password.encode())\n                os.close(w)\n                prefix += ['--password-file', f'fd:{r}', '--use-password', 'always']\n                pass_fds.append(r)\n            if pass_fds:\n                kw['pass_fds'] = tuple(pass_fds)\n            if isinstance(cmd, str):\n                cmd = ' '.join(prefix)\n            else:\n                cmd = prefix + list(cmd)","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/tui/handler.py#L86-L122","documentation":"Raised by remote_control() when the handler was created without allow_remote_control=True. The method builds a 'kitten @' command line to talk to kitty's remote control socket; if the flag was not set at construction, no socket/password setup happened, so the call is refused with a corrective hint.","triggerScenarios":"Calling handler.remote_control('set-color', ...) on a handler instantiated with allow_remote_control=False (the default), e.g. when a generic TUI handler is reused and later decides it needs remote control.","commonSituations":"Copy-pasting a kitten that uses remote_control into a handler created by a base class or template that passes allow_remote_control=False; refactoring where the flag gets lost; conditional code paths that only sometimes need remote control.","solutions":["Pass allow_remote_control=True when constructing the handler","Ensure the kitten runs via a kitty.conf map so KITTY_LISTEN_ON exists (required once the flag is on)","Restructure so remote_control is only called on handlers known to have the flag set"],"exampleFix":"# before\nhandler = ResultHandler(func)  # allow_remote_control defaults to False\nhandler.remote_control('send-text', text='hi')\n# after\nhandler = ResultHandler(func, allow_remote_control=True)\nhandler.remote_control('send-text', text='hi')","handlingStrategy":"type-guard","validationCode":"if not handler.allow_remote_control:\n    raise SystemExit('re-create handler with allow_remote_control=True')","typeGuard":"from kittens.tui.handler import ResultHandler\ndef supports_remote_control(h: ResultHandler) -> bool:\n    return bool(getattr(h, 'allow_remote_control', False))","tryCatchPattern":"try:\n    handler.remote_control(cmd)\nexcept ValueError as e:\n    if 'allow_remote_control=True' in str(e):\n        # recreate handler with the flag and retry\n        raise\n    raise","preventionTips":["Always construct handlers with allow_remote_control=True if any code path may call remote_control","Gate remote_control calls behind hasattr/flag checks"],"tags":["kitty","remote-control","precondition","kitten"],"backgroundTag":"api-precondition-violation","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}