kovidgoyal/kitty · error · SystemExit

The program: "' + a[0] + '" was not found

Error message

The program: "' + a[0] + '" was not found

What it means

Raised by exec_with_better_error() in kitty's SSH bootstrap when os.execlp(*a) fails with errno ENOENT, i.e. the program being exec'd (the user's shell such as zsh/fish/bash, or a target command) was not found on the remote PATH. Instead of a bare OSError traceback, the user gets a clear 'The program: X was not found' SystemExit. Any other OSError is re-raised unchanged.

Source

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

            env_vars = f.read()
        apply_env_vars(env_vars)
        data_dir = os.environ.pop('KITTY_SSH_KITTEN_DATA_DIR')
        if not os.path.isabs(data_dir):
            data_dir = os.path.join(HOME, data_dir)
        data_dir = os.path.abspath(data_dir)
        shell_integration_dir = os.path.join(data_dir, 'shell-integration')
        compile_terminfo(tdir + '/home')
        move(tdir + '/home', HOME)
        if os.path.exists(tdir + '/root'):
            move(tdir + '/root', '/')


def exec_with_better_error(*a):
    try:
        os.execlp(*a)
    except OSError as err:
        if err.errno == errno.ENOENT:
            raise SystemExit('The program: "' + a[0] + '" was not found')
        raise


def exec_zsh_with_integration():
    zdotdir = os.environ.get('ZDOTDIR') or ''
    if not zdotdir:
        zdotdir = HOME
        os.environ.pop('KITTY_ORIG_ZDOTDIR', None)  # ensure this is not propagated
    else:
        os.environ['KITTY_ORIG_ZDOTDIR'] = zdotdir
    # dont prevent zsh-newuser-install from running
    for q in ('.zshrc', '.zshenv', '.zprofile', '.zlogin'):
        if os.path.exists(os.path.join(zdotdir, q)):
            os.environ['ZDOTDIR'] = shell_integration_dir + '/zsh'
            exec_with_better_error(login_shell, os.path.basename(login_shell), '-l')
    os.environ.pop('KITTY_ORIG_ZDOTDIR', None)  # ensure this is not propagated

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Install the missing shell on the remote host (e.g. `apt install fish`)
  2. Fix the remote SHELL env var to point to an existing shell (edit /etc/passwd entry or set SHELL correctly)
  3. Explicitly select an installed shell: `kitty +kitten ssh --shell-integration=disabled user@host` then `chsh -s /bin/bash`
  4. As a workaround, run a shell that exists: `kitty +kitten ssh user@host bash`

Example fix

# before
kitty +kitten ssh myhost
# SystemExit: The program: "fish" was not found

# after
# on remote host:
sudo apt install fish   # or: chsh -s /bin/bash
Defensive patterns

Strategy: validation

Validate before calling

import os, shutil
shell = os.environ.get('SHELL', '/bin/sh')
shell_exists = shutil.which(shell) or os.path.exists(shell)

Prevention

When it happens

Trigger: SSH-ing with shell integration when the shell binary named by SHELL (or explicitly requested) doesn't exist on the remote host, e.g. SHELL=/usr/bin/fish on a host where fish isn't installed; exec_zsh/fish/bash_with_integration all funnel through this helper.

Common situations: SHELL environment variable on the remote host pointing to a shell that was never installed or was removed; logging into minimal containers/alpine images; SHELL set to a custom path not present in the image; migrating configs between machines with different shells installed.

Related errors


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