python/cpython · error · RuntimeError

insufficient terminal (horizontal)

Error message

insufficient terminal (horizontal)

What it means

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)'.

Source

Thrown at Lib/_pyrepl/unix_console.py:753

    def __enable_bracketed_paste(self) -> None:
        os.write(self.output_fd, b"\x1b[?2004h")

    def __disable_bracketed_paste(self) -> None:
        os.write(self.output_fd, b"\x1b[?2004l")

    def __setup_movement(self):
        """
        Set up the movement functions based on the terminal capabilities.
        """
        if 0 and self._hpa:  # hpa don't work in windows telnet :-(
            self.__move_x = self.__move_x_hpa
        elif self._cub and self._cuf:
            self.__move_x = self.__move_x_cub_cuf
        elif self._cub1 and self._cuf1:
            self.__move_x = self.__move_x_cub1_cuf1
        else:
            raise RuntimeError("insufficient terminal (horizontal)")

        if self._cuu and self._cud:
            self.__move_y = self.__move_y_cuu_cud
        elif self._cuu1 and self._cud1:
            self.__move_y = self.__move_y_cuu1_cud1
        else:
            raise RuntimeError("insufficient terminal (vertical)")

        if self._dch1:
            self.dch1 = self._dch1
        elif self._dch:
            self.dch1 = terminfo.tparm(self._dch, 1)
        else:
            self.dch1 = None

        if self._ich1:
            self.ich1 = self._ich1
        elif self._ich:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Set TERM=xterm (or xterm-256color) before launching Python.
  2. Install the full terminfo database (terminfo/ncurses-base package) or transfer the needed entry with infocmp | ssh host tic -.
  3. For non-interactive contexts, avoid the REPL entirely (run scripts) so UnixConsole is never constructed.

Example fix

# before
# docker run ... (no -t) TERM unset/dumb -> RuntimeError: insufficient terminal (horizontal)

# after
# docker run -t ...  # allocates tty, TERM defaults to a capable entry
# or: TERM=xterm-256color python
Defensive patterns

Strategy: fallback

Validate before calling

import os

def movement_capable():
    return os.environ.get('TERM', 'dumb') not in {'dumb', 'unknown', ''}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/244bb4f4de606845. Report an issue: GitHub.