kovidgoyal/kitty · error
The SSH kitten is meant to run inside a kitty window
Error message
The SSH kitten is meant to run inside a kitty window
What it means
The ssh kitten requires the KITTY_WINDOW_ID and KITTY_PID environment variables, which kitty sets only for processes running inside a kitty window. Missing either means it was launched outside kitty (or the env was stripped).
Source
Thrown at kittens/ssh/main.go:870
switch {
case errors.As(err, &invargs):
if invargs.Msg != "" {
fmt.Fprintln(os.Stderr, invargs.Msg)
}
return 1, unix.Exec(SSHExe(), []string{"ssh"}, os.Environ())
}
return 1, err
}
if passthrough {
return 1, unix.Exec(SSHExe(), utils.Concat([]string{"ssh"}, ssh_args, server_args), os.Environ())
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ssh_config_channel := ReadSSHConfig(ctx, ssh_args, server_args[0])
if os.Getenv("KITTY_WINDOW_ID") == "" || os.Getenv("KITTY_PID") == "" {
return 1, fmt.Errorf("The SSH kitten is meant to run inside a kitty window")
}
if !tty.IsTerminal(os.Stdin.Fd()) {
return 1, fmt.Errorf("The SSH kitten is meant for interactive use only, STDIN must be a terminal")
}
return run_ssh(ssh_args, server_args, found_extra_args, ssh_config_channel)
}
func EntryPoint(parent *cli.Command) {
create_cmd(parent, main)
}
func specialize_command(ssh *cli.Command) {
ssh.Usage = "arguments for the ssh command"
ssh.ShortDescription = "Truly convenient SSH"
ssh.HelpText = "The ssh kitten is a thin wrapper around the ssh command. It automatically enables shell integration on the remote host, re-uses existing connections to reduce latency, makes the kitty terminfo database available, etc. Its invocation is identical to the ssh command. For details on its usage, see :doc:`/kittens/ssh`."
ssh.IgnoreAllArgs = true
ssh.OnlyArgsAllowed = true
ssh.ArgCompleter = cli.CompletionForWrapper("ssh")View on GitHub (pinned to 6d5d0c4406)
Solutions
- Run it inside an actual kitty window (e.g. alias ssh='kitty +kitten ssh' inside kitty)
- If env vars are being stripped by a wrapper, ensure KITTY_WINDOW_ID and KITTY_PID are preserved
- On remote hosts, don't use the kitten; use plain ssh
Example fix
# before (in bash/gnome-terminal) kitty +kitten ssh host # after (inside kitty, e.g. in ~/.bashrc) alias ssh='kitty +kitten ssh'
Defensive patterns
Strategy: validation
Validate before calling
[ -n "$KITTY_WINDOW_ID" ] && [ -n "$KITTY_PID" ] || echo 'run inside kitty'
Prevention
- Detect kitty before aliasing ssh to the kitten
- Preserve KITTY_* env vars in wrappers
When it happens
Trigger: Running kitty +kitten ssh (or the ssh kitten binary) from a non-kitty terminal, shell, or a launcher that clears the environment.
Common situations: Using the ssh kitten binary in tmux/screen/another terminal emulator; env -i or sanitized environments; ssh'ing into a remote and invoking it there.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
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/eae1b91e6bcaf790.
Report an issue: GitHub.