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
- 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.
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
- 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.
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
- insufficient terminal (vertical)
- terminal doesn't have the required {cap} capability
- Windows 10 TH2 or later required
- \C must be followed by `-' (char %d of %s)
- doubled \C- (char %d of %s)
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/244bb4f4de606845.
Report an issue: GitHub.