kovidgoyal/kitty · error
The SSH kitten is meant for interactive use only, STDIN must
Error message
The SSH kitten is meant for interactive use only, STDIN must be a terminal
What it means
Immediately after the kitty-window check, the kitten verifies stdin is a TTY. Non-interactive stdin (pipe, file, closed) makes the interactive SSH session impossible, so it aborts.
Source
Thrown at kittens/ssh/main.go:873
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")
}
func test_integration_with_python(args []string) (rc int, err error) {View on GitHub (pinned to 6d5d0c4406)
Solutions
- Don't pipe into the ssh kitten; use plain ssh host 'cmd' for non-interactive commands
- Ensure the kitten runs with an interactive terminal on stdin
- Check nothing in the shell chain closes or redirects stdin
Example fix
# before echo ls | kitty +kitten ssh host # after kitty +kitten ssh host # interactive # or for scripting: ssh host ls
Defensive patterns
Strategy: validation
Validate before calling
[ -t 0 ] || { echo 'stdin must be a terminal'; exit 1; } Prevention
- Use plain ssh for scripted/non-interactive commands
- Never pipe stdin into kitty +kitten ssh
When it happens
Trigger: kitty +kitten ssh with stdin redirected from a pipe/file, run under a non-interactive context, or with stdin closed (<&-).
Common situations: Scripted use like echo cmd | kitty +kitten ssh host; cron jobs; running inside CI; chaining commands with pipes into the kitten.
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/092ebdf1fd664e43.
Report an issue: GitHub.