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_dataView on GitHub (pinned to 6d5d0c4406)
Solutions
- Read the message text — it is literally the remote host's output and names the real problem
- Ensure the remote login shell is POSIX-compatible and that base64 exists on the host
- Silence startup noise on the remote host (avoid echo/printf in .bashrc for non-interactive sessions)
- 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
- Make remote shell startup files quiet for non-interactive sessions
- Verify base64 and a POSIX shell exist on target hosts before using kitty ssh integration
- Test problematic hosts with --shell-integration=disabled to isolate handshake issues
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
- This should be run as kitten ssh
- Incorrect owner on pwfile: uid={shm.stats.st_uid} gid={shm.s
- Incorrect permissions on pwfile: 0o{mode:03o}
- Incorrect password
- Incorrect request id: {rq_id!r} expecting the KITTY_PID-KITT
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/b785a592abf875f2.
Report an issue: GitHub.