{"record":{"id":"071d8be87d4248cd","repo":"kovidgoyal/kitty","slug":"failed-to-open-controlling-terminal-with-error-w-071d8b","errorCode":null,"errorMessage":"Failed to open controlling terminal with error: %w","messagePattern":"Failed to open controlling terminal with error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/ssh/main.go","lineNumber":758,"sourceCode":"\t\tcmcmd = append(cmcmd, \"-R\", \"0:\"+listen_on, \"-O\", \"forward\")\n\t\tcmcmd = append(cmcmd, \"--\", hostname)\n\t\tc := exec.Command(cmcmd[0], cmcmd[1:]...)\n\t\tb := bytes.Buffer{}\n\t\tc.Stdout = &b\n\t\tc.Stderr = os.Stderr\n\t\tif err := c.Run(); err != nil {\n\t\t\treturn 1, fmt.Errorf(\"%s\\nSetup of port forward in SSH ControlMaster failed with error: %w\", b.String(), err)\n\t\t}\n\t\tport, err := strconv.Atoi(strings.TrimSpace(b.String()))\n\t\tif err != nil {\n\t\t\tos.Stderr.Write(b.Bytes())\n\t\t\treturn 1, fmt.Errorf(\"Setup of port forward in SSH ControlMaster failed with error: invalid resolved port returned: %s\", b.String())\n\t\t}\n\t\tcd.listen_on = \"tcp:localhost:\" + strconv.Itoa(port)\n\t}\n\tterm, err := tty.OpenControllingTerm(tty.SetNoEcho)\n\tif err != nil {\n\t\treturn 1, fmt.Errorf(\"Failed to open controlling terminal with error: %w\", err)\n\t}\n\tcd.echo_on = term.WasEchoOnOriginally()\n\tcd.host_opts, cd.literal_env = host_opts, literal_env\n\tcd.request_data = need_to_request_data\n\tcd.hostname_for_match, cd.username = hostname_for_match, uname\n\tescape_codes_to_set_colors, err := change_colors(cd.host_opts.Color_scheme)\n\tif err == nil {\n\t\terr = term.WriteAllString(escape_codes_to_set_colors + loop.SAVE_PRIVATE_MODE_VALUES + loop.PUSH_KEY_FLAGS + loop.HANDLE_TERMIOS_SIGNALS.EscapeCodeToSet())\n\t}\n\tif err != nil {\n\t\treturn 1, err\n\t}\n\trestore_escape_codes := loop.RESTORE_PRIVATE_MODE_VALUES + loop.POP_KEY_FLAGS + loop.HANDLE_TERMIOS_SIGNALS.EscapeCodeToReset()\n\tif escape_codes_to_set_colors != \"\" {\n\t\trestore_escape_codes += \"\\x1b[#Q\"\n\t}\n\tsigs := make(chan os.Signal, 8)\n\tsignal.Notify(sigs, unix.SIGINT, unix.SIGTERM)","sourceCodeStart":740,"sourceCodeEnd":776,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/ssh/main.go#L740-L776","documentation":"The SSH kitten opens the controlling terminal (with echo disabled) to run interactively; tty.OpenControllingTerm failed, wrapping the OS error. Usually means stdin/stdout is not attached to a TTY or the terminal device can't be reopened.","triggerScenarios":"Running the ssh kitten where /dev/tty cannot be opened or set to no-echo — piped stdin/stdout, detached process, container without a TTY, or permissions on the terminal device.","commonSituations":"Running kitty +kitten ssh from a script, CI, docker exec without -t, or an environment where the process has no controlling terminal.","solutions":["Run the ssh kitten inside an interactive kitty window/tab with a real TTY","If in a container, allocate a TTY (docker run -it / exec -it)","Avoid piping stdin/stdout into kitty +kitten ssh; use plain ssh for non-interactive use"],"exampleFix":"# before (no tty)\ndocker exec mycontainer kitty +kitten ssh host\n\n# after\ndocker exec -it mycontainer kitty +kitten ssh host","handlingStrategy":"validation","validationCode":"[ -t 0 ] && [ -t 1 ] || { echo 'needs a TTY'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only run the ssh kitten in an interactive terminal","Allocate TTYs in containers with -it"],"tags":["kitty","ssh","tty","terminal"],"backgroundTag":"no-controlling-terminal","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}