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

  1. Don't pipe into the ssh kitten; use plain ssh host 'cmd' for non-interactive commands
  2. Ensure the kitten runs with an interactive terminal on stdin
  3. 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

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


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