{"record":{"id":"be37f4b88b31ebb5","repo":"gravitational/teleport","slug":"failed-to-retrieve-stdout-mode-w","errorCode":null,"errorMessage":"failed to retrieve stdout mode: %w","messagePattern":"failed to retrieve stdout mode: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/client/terminal/terminal_windows.go","lineNumber":49,"sourceCode":"\t\"github.com/Azure/go-ansiterm/winterm\"\n\t\"github.com/gravitational/trace\"\n\t\"github.com/moby/term\"\n\n\t\"github.com/gravitational/teleport/lib/client/tncon\"\n\t\"github.com/gravitational/teleport/lib/utils\"\n)\n\n// initTerminal configures the terminal for raw, VT compatible output and\n// optionally input. The returned function should be called before program\n// exit to ensure the terminal is reset, otherwise it will be left in a broken\n// state.\nfunc initTerminal(input bool) (func(), error) {\n\tstdoutFd := int(syscall.Stdout)\n\tstdinFd := int(syscall.Stdin)\n\n\toldOutMode, err := winterm.GetConsoleMode(uintptr(stdoutFd))\n\tif err != nil {\n\t\treturn func() {}, fmt.Errorf(\"failed to retrieve stdout mode: %w\", err)\n\t}\n\n\toldInMode, err := winterm.GetConsoleMode(uintptr(stdinFd))\n\tif err != nil {\n\t\treturn func() {}, fmt.Errorf(\"failed to retrieve stdout mode: %w\", err)\n\t}\n\n\tnewOutMode := oldOutMode | winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING | winterm.DISABLE_NEWLINE_AUTO_RETURN\n\n\terr = winterm.SetConsoleMode(uintptr(stdoutFd), newOutMode)\n\tif err != nil {\n\t\treturn func() {}, fmt.Errorf(\"failed to set stdout mode: %w\", err)\n\t}\n\n\tif input {\n\t\tnewInMode := oldInMode\n\t\tnewInMode &^= winterm.ENABLE_ECHO_INPUT\n\t\tnewInMode &^= winterm.ENABLE_LINE_INPUT","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/lib/client/terminal/terminal_windows.go#L31-L67","documentation":"initTerminal calls winterm.GetConsoleMode on the Windows stdout handle (syscall.Stdout) before enabling VT processing. If the OS refuses to read the console mode, the call is aborted and this wrapped error is returned through Terminal.InitRaw. It means the process's standard output is not an interactive Windows console buffer (or the console API failed), so raw/VT terminal mode cannot be established.","triggerScenarios":"Calling Terminal.InitRaw on Windows when GetConsoleMode(stdout) fails: stdout is redirected to a file or pipe, the process runs without an attached console (e.g. a service, scheduled task, or CI runner), or the console host returns an error for the pseudo handle.","commonSituations":"Running `tsh ssh` or another Teleport client interactively with `> out.log` redirection; invoking the client from a non-console parent (IDE run tool, ssh without a pty, Windows service); using a legacy terminal host that does not expose console mode APIs for the stdout handle.","solutions":["Run the client in a real interactive Windows console (conhost or Windows Terminal) with stdout attached to the console, not redirected.","Before calling InitRaw, check term.IsTerminal(os.Stdout.Fd()) (moby/term) and skip raw mode when stdout is not a console.","If running programmatically or in CI, use the library in non-interactive mode instead of requesting raw terminal capture.","Ensure the process has an attached console (e.g. launch via a terminal rather than a detached/service context); use AttachConsole/AllocConsole if embedding."],"exampleFix":"// before\ncleanup, err := term.InitRaw(true)\nif err != nil {\n    return err\n}\n\n// after\nif !term.IsTerminal(os.Stdout.Fd()) {\n    return errors.New(\"stdout is not an interactive console; cannot enable raw mode\")\n}\ncleanup, err := term.InitRaw(true)\nif err != nil {\n    return trace.Wrap(err)\n}","handlingStrategy":"validation","validationCode":"import \"github.com/moby/term\"\n\nif !term.IsTerminal(os.Stdout.Fd()) {\n    return errors.New(\"stdout is not an interactive Windows console; raw terminal mode unavailable\")\n}","typeGuard":"func isConsole(f *os.File) bool {\n    return term.IsTerminal(f.Fd())\n}","tryCatchPattern":"cleanup, err := t.InitRaw(input)\nif err != nil {\n    var consoleErr *fmt.Errorf\n    if errors.As(err, &consoleErr) && strings.Contains(err.Error(), \"failed to retrieve stdout mode\") {\n        log.Warn(\"no interactive console on stdout; disabling raw mode\")\n        cleanup = func() {}\n    } else {\n        return trace.Wrap(err)\n    }\n}","preventionTips":["Always run interactive Teleport clients from a real terminal (conhost/Windows Terminal), not with redirected stdout.","Guard InitRaw behind term.IsTerminal(os.Stdout.Fd()) checks.","In CI or scripted contexts, use non-interactive modes instead of raw terminal capture."],"tags":["windows","terminal","console-api","io"],"backgroundTag":"console-mode-not-available","analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}