{"record":{"id":"244bb4f4de606845","repo":"python/cpython","slug":"insufficient-terminal-horizontal","errorCode":null,"errorMessage":"insufficient terminal (horizontal)","messagePattern":"insufficient terminal \\(horizontal\\)","errorType":"console","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Lib/_pyrepl/unix_console.py","lineNumber":753,"sourceCode":"\n    def __enable_bracketed_paste(self) -> None:\n        os.write(self.output_fd, b\"\\x1b[?2004h\")\n\n    def __disable_bracketed_paste(self) -> None:\n        os.write(self.output_fd, b\"\\x1b[?2004l\")\n\n    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:","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyrepl/unix_console.py#L735-L771","documentation":"RuntimeError from UnixConsole.__setup_movement (Lib/_pyrepl/unix_console.py). To move the cursor horizontally the console needs either hpa (disabled by the hardcoded '0 and' branch), or cub plus cuf, or cub1 plus cuf1 capabilities. A terminfo entry lacking all of these cannot position the cursor left/right, so setup aborts with 'insufficient terminal (horizontal)'.","triggerScenarios":"Starting the pyrepl REPL with TERM pointing to an entry that defines no cursor-left/right strings (dumb, unknown, printer entries, or a corrupted/minimal terminfo db). The hpa branch is dead code ('if 0 and ...'), so cub/cuf or cub1/cuf1 are the only live options.","commonSituations":"TERM=dumb in cron jobs or containers that still reach REPL code; minimal Docker images without terminfo; homebrew terminfo entries from exotic terminals; remote systems missing the entry for the local terminal emulator after forwarding TERM over SSH.","solutions":["Set TERM=xterm (or xterm-256color) before launching Python.","Install the full terminfo database (terminfo/ncurses-base package) or transfer the needed entry with infocmp | ssh host tic -.","For non-interactive contexts, avoid the REPL entirely (run scripts) so UnixConsole is never constructed."],"exampleFix":"# before\n# docker run ... (no -t) TERM unset/dumb -> RuntimeError: insufficient terminal (horizontal)\n\n# after\n# docker run -t ...  # allocates tty, TERM defaults to a capable entry\n# or: TERM=xterm-256color python","handlingStrategy":"fallback","validationCode":"import os\n\ndef movement_capable():\n    return os.environ.get('TERM', 'dumb') not in {'dumb', 'unknown', ''}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set TERM=xterm in headless environments that still run interactive code.","Keep terminfo databases installed; verify with infocmp $TERM listing cub/cuf.","Prefer PYTHON_BASIC_REPL=1 when no real terminal is attached."],"tags":["python","pyrepl","terminfo","cursor-movement","terminal"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}