kovidgoyal/kitty · error · SystemExit

line.decode('utf-8', 'replace').rstrip()

Error message

line.decode('utf-8', 'replace').rstrip()

What it means

Raised by iter_base64_data() in kitty's SSH bootstrap when, during the base64 handshake that transfers files/data to the remote host, a line other than b'OK' arrives after the start marker. The remote shell was expected to acknowledge with OK; instead it emitted something else, so the script surfaces that decoded line as the error message via SystemExit. The message content is whatever the remote side printed.

Source

Thrown at shell-integration/ssh/bootstrap.py:185

        getattr(sys.stderr, 'buffer', sys.stderr).write(output)
        raise SystemExit('Failed to compile the terminfo database')


def iter_base64_data(f):
    global leading_data
    started = 0
    while True:
        line = f.readline().rstrip()
        if started == 0:
            if line == b'KITTY_DATA_START':
                started = 1
            else:
                leading_data += line
        elif started == 1:
            if line == b'OK':
                started = 2
            else:
                raise SystemExit(line.decode('utf-8', 'replace').rstrip())
        else:
            if line == b'KITTY_DATA_END':
                break
            yield line


@contextlib.contextmanager
def temporary_directory(dir, prefix):
    # tempfile.TemporaryDirectory not available in python2
    tdir = tempfile.mkdtemp(dir=dir, prefix=prefix)
    try:
        yield tdir
    finally:
        shutil.rmtree(tdir)


def get_data():
    global data_dir, shell_integration_dir, leading_data

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Read the message text — it is literally the remote host's output and names the real problem
  2. Ensure the remote login shell is POSIX-compatible and that base64 exists on the host
  3. Silence startup noise on the remote host (avoid echo/printf in .bashrc for non-interactive sessions)
  4. Try `kitty +kitten ssh user@host --shell-integration=disabled` (or a plain ssh) to confirm the host itself works, then re-enable

Example fix

# before
kitty +kitten ssh weirdhost
# SystemExit: /bin/sh: base64: not found

# after
# install coreutils/busybox on the host, or:
kitty +kitten ssh --shell-integration=disabled weirdhost
Defensive patterns

Strategy: fallback

Validate before calling

import shutil
ok = shutil.which('base64') is not None and shutil.which('sh') is not None

Prevention

When it happens

Trigger: kitty ssh bootstrap sends a POSIX-shell/base64 payload to the remote host; if the remote shell prints a warning/error (e.g. 'base64: not found', a shell error, or a login banner in the wrong place) before acknowledging OK, this SystemExit fires with that text.

Common situations: Remote hosts lacking base64 or with a non-POSIX shell; shell startup files (.bashrc/.profile) printing output that corrupts the handshake; hosts with forced motd/login scripts interleaving output; ancient busybox shells with nonstandard behavior.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/b785a592abf875f2. Report an issue: GitHub.