python/cpython · error · InvalidTerminal

terminal doesn't have the required {cap} capability

Error message

terminal doesn't have the required {cap} capability

What it means

InvalidTerminal exception from the _my_getstr helper inside UnixConsole.__init__ (Lib/_pyrepl/unix_console.py). Required terminfo string capabilities (bel, clear, and other non-optional caps) must exist in the loaded terminfo entry for the current TERM; if terminfo.TermInfo.get(cap) returns None for a required cap, the console refuses to start with this message naming the missing capability.

Source

Thrown at Lib/_pyrepl/unix_console.py:238

        )

        try:
            self.__input_fd_set(tcgetattr(self.input_fd), ignore=frozenset())
        except _error as e:
            raise RuntimeError(f"termios failure ({e.args[1]})")

        @overload
        def _my_getstr(
            cap: str, optional: Literal[False] = False
        ) -> bytes: ...

        @overload
        def _my_getstr(cap: str, optional: bool) -> bytes | None: ...

        def _my_getstr(cap: str, optional: bool = False) -> bytes | None:
            r = self.terminfo.get(cap)
            if not optional and r is None:
                raise InvalidTerminal(
                    f"terminal doesn't have the required {cap} capability"
                )
            return r

        self._bel = _my_getstr("bel")
        self._civis = _my_getstr("civis", optional=True)
        self._clear = _my_getstr("clear")
        self._cnorm = _my_getstr("cnorm", optional=True)
        self._cub = _my_getstr("cub", optional=True)
        self._cub1 = _my_getstr("cub1", optional=True)
        self._cud = _my_getstr("cud", optional=True)
        self._cud1 = _my_getstr("cud1", optional=True)
        self._cuf = _my_getstr("cuf", optional=True)
        self._cuf1 = _my_getstr("cuf1", optional=True)
        self._cup = _my_getstr("cup")
        self._cuu = _my_getstr("cuu", optional=True)
        self._cuu1 = _my_getstr("cuu1", optional=True)
        self._dch1 = _my_getstr("dch1", optional=True)

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Set TERM to a full-featured entry present on the machine: TERM=xterm (or xterm-256color) and retry.
  2. Install/repair the terminfo database (ncurses-base/terminfo package on Debian/Ubuntu) or copy the missing entry with infocmp/tic from a working host.
  3. If the terminal genuinely lacks the cap, pyrepl cannot run on it — use PYTHON_BASIC_REPL=1 or TERM=xterm emulation.

Example fix

# before
# TERM=dumb python   -> InvalidTerminal: terminal doesn't have the required bel capability

# after
# TERM=xterm python
Defensive patterns

Strategy: fallback

Validate before calling

import shutil, os

def terminfo_ok():
    term = os.environ.get('TERM', '')
    return term not in {'', 'dumb', 'unknown'} and bool(shutil.which('infocmp'))

Try / catch

try:
    start_repl()
except InvalidTerminal as e:
    os.environ['TERM'] = 'xterm'
    start_repl()  # retry with a capable entry

Prevention

When it happens

Trigger: Starting pyrepl/UnixConsole with TERM set to a minimal or broken entry — e.g. TERM=dumb, TERM=unknown, a stripped-down terminfo database, or TERM values with no 'bel'/'clear' strings (some printer/legacy entries). Optional caps are fetched with optional=True and don't raise; the non-optional list does.

Common situations: SSH into embedded/minimal containers with a truncated /usr/share/terminfo; TERM inherited from a GUI terminal not present on the remote host (e.g. alacritty on an old server); CI runners with TERM unset defaulting to dumb; custom TERMCAP overrides missing required strings.

Related errors


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