kovidgoyal/kitty · error · SystemExit

{exe} does not exist

Error message

{exe} does not exist

What it means

Raised by kitty's `launch` entry point when the executable path given (typically via `kitty +launch` or a kit that delegates to a script) does not exist on disk. It is a SystemExit with a clear message, emitted right before runpy would attempt to execute the file.

Source

Thrown at kitty/entry_points.py:78

    sys.argv = args[1:]
    try:
        exe = args[1]
    except IndexError:
        raise SystemExit(
            'usage: kitty +launch script.py [arguments to be passed to script.py ...]\n\n'
            'script.py will be run with full access to kitty code. If script.py is '
            'prefixed with a : it will be searched for in PATH. If script.py is a directory '
            'the __main__.py file inside it is run just as with the normal Python interpreter.'
        )
    if exe.startswith(':'):
        import shutil

        q = shutil.which(exe[1:])
        if not q:
            raise SystemExit(f'{exe[1:]} not found in PATH')
        exe = q
    if not os.path.exists(exe):
        raise SystemExit(f'{exe} does not exist')
    runpy.run_path(exe, run_name='__main__')


def shebang(args: list[str]) -> None:
    from kitty.constants import kitten_exe

    os.execvp(kitten_exe(), ['kitten', '__shebang__', 'confirm-if-needed'] + args[1:])


def run_kitten(args: list[str]) -> None:
    try:
        kitten = args[1]
    except IndexError:
        from kittens.runner import list_kittens

        list_kittens()
        raise SystemExit(1)
    sys.argv = args[1:]

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Verify the path exists from the same cwd kitty runs in (ls the exact value passed).
  2. If the script should be found on PATH, prefix it with '!' so the earlier shutil.which branch resolves it.
  3. Fix the wrapper/config that constructs the path (expanduser/expandvars, absolute paths).

Example fix

// before
kitty +launch /opt/scripts/init.py  # path moved
// after
kitty +launch /opt/scripts-new/init.py
# or rely on PATH lookup:
kitty +launch '!my-init-script.py'
Defensive patterns

Strategy: validation

Validate before calling

import os
if not os.path.exists(exe):
    raise FileNotFoundError(exe)

Prevention

When it happens

Trigger: Calling kitty/entry_points.py:launch(exe) where exe is not a `!`-prefixed PATH lookup (that case is handled earlier) and os.path.exists(exe) is False — e.g. passing a relative path from a different cwd, a typo'd path, or a deleted script.

Common situations: Custom kitten/launch scripts referenced by absolute path that was moved or is on a different machine; running kitty from a wrapper that computes the script path incorrectly; NFS/sshfs mounts not yet available.

Related errors


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