{"record":{"id":"eae1b91e6bcaf790","repo":"kovidgoyal/kitty","slug":"the-ssh-kitten-is-meant-to-run-inside-a-kitty-wind","errorCode":null,"errorMessage":"The SSH kitten is meant to run inside a kitty window","messagePattern":"The SSH kitten is meant to run inside a kitty window","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/ssh/main.go","lineNumber":870,"sourceCode":"\t\tswitch {\n\t\tcase errors.As(err, &invargs):\n\t\t\tif invargs.Msg != \"\" {\n\t\t\t\tfmt.Fprintln(os.Stderr, invargs.Msg)\n\t\t\t}\n\t\t\treturn 1, unix.Exec(SSHExe(), []string{\"ssh\"}, os.Environ())\n\t\t}\n\t\treturn 1, err\n\t}\n\tif passthrough {\n\t\treturn 1, unix.Exec(SSHExe(), utils.Concat([]string{\"ssh\"}, ssh_args, server_args), os.Environ())\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tssh_config_channel := ReadSSHConfig(ctx, ssh_args, server_args[0])\n\n\tif os.Getenv(\"KITTY_WINDOW_ID\") == \"\" || os.Getenv(\"KITTY_PID\") == \"\" {\n\t\treturn 1, fmt.Errorf(\"The SSH kitten is meant to run inside a kitty window\")\n\t}\n\tif !tty.IsTerminal(os.Stdin.Fd()) {\n\t\treturn 1, fmt.Errorf(\"The SSH kitten is meant for interactive use only, STDIN must be a terminal\")\n\t}\n\treturn run_ssh(ssh_args, server_args, found_extra_args, ssh_config_channel)\n}\n\nfunc EntryPoint(parent *cli.Command) {\n\tcreate_cmd(parent, main)\n}\n\nfunc specialize_command(ssh *cli.Command) {\n\tssh.Usage = \"arguments for the ssh command\"\n\tssh.ShortDescription = \"Truly convenient SSH\"\n\tssh.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`.\"\n\tssh.IgnoreAllArgs = true\n\tssh.OnlyArgsAllowed = true\n\tssh.ArgCompleter = cli.CompletionForWrapper(\"ssh\")","sourceCodeStart":852,"sourceCodeEnd":888,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/ssh/main.go#L852-L888","documentation":"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).","triggerScenarios":"Running kitty +kitten ssh (or the ssh kitten binary) from a non-kitty terminal, shell, or a launcher that clears the environment.","commonSituations":"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.","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"],"exampleFix":"# before (in bash/gnome-terminal)\nkitty +kitten ssh host\n\n# after (inside kitty, e.g. in ~/.bashrc)\nalias ssh='kitty +kitten ssh'","handlingStrategy":"validation","validationCode":"[ -n \"$KITTY_WINDOW_ID\" ] && [ -n \"$KITTY_PID\" ] || echo 'run inside kitty'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Detect kitty before aliasing ssh to the kitten","Preserve KITTY_* env vars in wrappers"],"tags":["kitty","ssh","environment","detection"],"backgroundTag":"missing-env-var","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}