kovidgoyal/kitty · error · SystemExit

This should be run as kitten ssh

Error message

This should be run as kitten ssh

What it means

kitty's ssh kitten main() is a stub that always raises SystemExit('This should be run as kitten ssh'). The actual functionality lives in the wrapper machinery (the '__wrapper_of__' branch shown in the source) that kitty installs when you use the kitten; direct execution only hits the placeholder.

Source

Thrown at kittens/ssh/main.py:340

    long_text="""
Number of digits for the generated TOTP codes. Default is 6.
""",
)

opt(
    'totp_period',
    '30',
    option_type='int',
    long_text="""
Time period in seconds for the TOTP code validity. Default is 30.
""",
)

egr()  # }}}


def main(args: list[str]) -> str | None:
    raise SystemExit('This should be run as kitten ssh')


if __name__ == '__main__':
    main([])
elif __name__ == '__wrapper_of__':
    cd = getattr(sys, 'cli_docs')
    cd['wrapper_of'] = 'ssh'
elif __name__ == '__conf__':
    setattr(sys, 'options_definition', definition)
elif __name__ == '__extra_cli_parsers__':
    setattr(sys, 'extra_cli_parsers', {'copy': option_text()})

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Run it as `kitten ssh host` from inside kitty (it needs kitty's wrapper to handle asking for passwords/UI).
  2. Ensure the kitty ssh kitten is enabled: kitty.conf should not have `map ctrl+shift+enter` overridden oddly; use `kitten ssh user@host` or map it.
  3. For scripting/tests, call the underlying helpers (e.g. modify_argv_for_launch_with_cwd, utils functions) instead of main().
  4. If you need plain ssh without kitty integration, just run ssh directly rather than this stub.

Example fix

# before
python kittens/ssh/main.py  # SystemExit: This should be run as kitten ssh
main([])                    # same

# after
kitten ssh user@host
Defensive patterns

Strategy: fallback

Validate before calling

import shutil, subprocess, sys

def ssh_via_kitten(host: str) -> int:
    if shutil.which('kitten') is None or not os.environ.get('KITTY_WINDOW_ID'):
        return subprocess.call(['ssh', host])  # plain ssh fallback
    return subprocess.call(['kitten', 'ssh', host])

Prevention

When it happens

Trigger: Executing kittens/ssh/main.py directly with python, or importing it and calling main(). The real code paths run only under kitty's runner with __name__ == '__wrapper_of__' or '__run_kitten__'.

Common situations: Trying to use kitty's ssh kitten logic in a plain shell by running the file; CI scripts or tests calling main(); developers reading the source and assuming main() is the entrypoint; running inside a non-kitty terminal where kitty isn't on PATH so they resort to the raw file.

Related errors


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