{"record":{"id":"7929c91e906538f3","repo":"python/cpython","slug":"insufficient-terminal-vertical","errorCode":null,"errorMessage":"insufficient terminal (vertical)","messagePattern":"insufficient terminal \\(vertical\\)","errorType":"console","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Lib/_pyrepl/unix_console.py","lineNumber":760,"sourceCode":"    def __setup_movement(self):\n        \"\"\"\n        Set up the movement functions based on the terminal capabilities.\n        \"\"\"\n        if 0 and self._hpa:  # hpa don't work in windows telnet :-(\n            self.__move_x = self.__move_x_hpa\n        elif self._cub and self._cuf:\n            self.__move_x = self.__move_x_cub_cuf\n        elif self._cub1 and self._cuf1:\n            self.__move_x = self.__move_x_cub1_cuf1\n        else:\n            raise RuntimeError(\"insufficient terminal (horizontal)\")\n\n        if self._cuu and self._cud:\n            self.__move_y = self.__move_y_cuu_cud\n        elif self._cuu1 and self._cud1:\n            self.__move_y = self.__move_y_cuu1_cud1\n        else:\n            raise RuntimeError(\"insufficient terminal (vertical)\")\n\n        if self._dch1:\n            self.dch1 = self._dch1\n        elif self._dch:\n            self.dch1 = terminfo.tparm(self._dch, 1)\n        else:\n            self.dch1 = None\n\n        if self._ich1:\n            self.ich1 = self._ich1\n        elif self._ich:\n            self.ich1 = terminfo.tparm(self._ich, 1)\n        else:\n            self.ich1 = None\n\n        self.__move = self.__move_short\n\n    @staticmethod","sourceCodeStart":742,"sourceCodeEnd":778,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyrepl/unix_console.py#L742-L778","documentation":"RuntimeError from UnixConsole.__setup_movement (Lib/_pyrepl/unix_console.py). Vertical cursor movement requires either the parameterized cuu+cud pair or the single-step cuu1+cud1 pair. A terminal entry with none of the four capabilities raises 'insufficient terminal (vertical)' during console init; it typically appears together with (or right after) the horizontal variant on the same crippled TERM entry.","triggerScenarios":"Same class as the horizontal failure: TERM=dumb/unknown or a terminfo entry lacking cursor-up/down strings when the pyrepl REPL initializes its movement functions in __setup_movement.","commonSituations":"Headless containers, cron contexts, or embedded systems whose terminfo db is stripped; TERMCAP-based legacy environments; TERM forwarded over SSH to a host that lacks that entry (falls back to a minimal one).","solutions":["Set TERM=xterm or another fully capable entry before starting Python.","Install/repair terminfo databases (ncurses-base/terminfo packages; infocmp/tic to copy entries).","Keep the REPL out of non-tty code paths: guard interactive entry with sys.stdin.isatty()."],"exampleFix":"# before\n# TERM=dumb python -i   -> RuntimeError: insufficient terminal (vertical)\n\n# after\n# TERM=xterm python -i","handlingStrategy":"fallback","validationCode":"import os\n\ndef vertical_movement_capable():\n    # crude proxy: full terminfo entries for common TERMs define cuu/cud\n    return os.environ.get('TERM', '') not in {'', 'dumb', 'unknown'}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Same root cause as the horizontal variant: fix TERM/terminfo.","Verify capability presence with 'infocmp $TERM | grep -E \"cuu|cud\"'.","Run REPL only under a real tty; scripts never construct UnixConsole."],"tags":["python","pyrepl","terminfo","cursor-movement","terminal"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}