{"record":{"id":"5ae0ebbaa273fa25","repo":"charmbracelet/bubbletea","slug":"error-setting-console-mode-w","errorCode":null,"errorMessage":"error setting console mode: %w","messagePattern":"error setting console mode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tty_windows.go","lineNumber":31,"sourceCode":"func (p *Program) initInput() (err error) {\n\t// Save stdin state and enable VT input\n\t// We also need to enable VT\n\t// input here.\n\tif f, ok := p.input.(term.File); ok && term.IsTerminal(f.Fd()) {\n\t\tp.ttyInput = f\n\t\tp.previousTtyInputState, err = term.MakeRaw(p.ttyInput.Fd())\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error making terminal raw: %w\", err)\n\t\t}\n\n\t\t// Enable VT input\n\t\tvar mode uint32\n\t\tif err := windows.GetConsoleMode(windows.Handle(p.ttyInput.Fd()), &mode); err != nil {\n\t\t\treturn fmt.Errorf(\"error getting console mode: %w\", err)\n\t\t}\n\n\t\tif err := windows.SetConsoleMode(windows.Handle(p.ttyInput.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil {\n\t\t\treturn fmt.Errorf(\"error setting console mode: %w\", err)\n\t\t}\n\t}\n\n\t// Save output screen buffer state and enable VT processing.\n\tif f, ok := p.output.(term.File); ok && term.IsTerminal(f.Fd()) {\n\t\tp.ttyOutput = f\n\t\tp.previousOutputState, err = term.GetState(f.Fd())\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error getting terminal state: %w\", err)\n\t\t}\n\n\t\tvar mode uint32\n\t\tif err := windows.GetConsoleMode(windows.Handle(p.ttyOutput.Fd()), &mode); err != nil {\n\t\t\treturn fmt.Errorf(\"error getting console mode: %w\", err)\n\t\t}\n\n\t\tif err := windows.SetConsoleMode(windows.Handle(p.ttyOutput.Fd()),\n\t\t\tmode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING|","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/charmbracelet/bubbletea/blob/351d2159f8d8a85613aa2a6e98c8c63df3c98623/tty_windows.go#L13-L49","documentation":"Windows initInput() enables virtual terminal (VT) input by OR-ing ENABLE_VIRTUAL_TERMINAL_INPUT into the console mode and calling windows.SetConsoleMode on stdin. This error means the mode update was rejected — most commonly because the console does not support VT input (pre-Windows-10 consoles, legacy conhost) or the handle is invalid. Since VT escape sequences are how Bubble Tea reads keys and mouse, initialization fails and Program.Run() returns this error.","triggerScenarios":"windows.SetConsoleMode(stdin, mode|ENABLE_VIRTUAL_TERMINAL_INPUT) fails on Windows versions older than 10 1511, on some legacy or restricted console hosts, or when the input handle was invalidated between the GetConsoleMode and SetConsoleMode calls.","commonSituations":"Running the .exe on Windows 7/8 or Windows Server 2012/2012 R2, terminals that host their own non-VT console emulation, locked-down terminal servers where SetConsoleMode is denied, and CI agents using a bare conhost without VT enabled.","solutions":["Run in Windows Terminal, a recent conhost on Windows 10 1511+, or a ConPTY-based host — VT input is a hard requirement of this code path.","On older Windows, run the program inside Windows Terminal via WSL, or wrap it in a ConPTY yourself and pass that pty to tea.WithInput/tea.WithOutput.","Verify support before starting: call GetConsoleMode and attempt a SetConsoleMode with ENABLE_VIRTUAL_TERMINAL_INPUT yourself; if it fails, fall back to tea.WithInput(nil) and a plain UI.","Check the wrapped error code — ERROR_INVALID_PARAMETER means unsupported flag (old console); ERROR_INVALID_HANDLE means a dead handle."],"exampleFix":"// before\np := tea.NewProgram(model{})\nif _, err := p.Run(); err != nil {\n    log.Fatalf(\"%v\", err) // error setting console mode: The parameter is incorrect\n}\n\n// after: probe VT support, degrade gracefully\nif !vtInputSupported() {\n    p = tea.NewProgram(model{}, tea.WithoutRenderer())\n}\nif _, err := p.Run(); err != nil { log.Fatal(err) }\n\nfunc vtInputSupported() bool {\n    var mode uint32\n    h := windows.Handle(os.Stdin.Fd())\n    if err := windows.GetConsoleMode(h, &mode); err != nil { return false }\n    return windows.SetConsoleMode(h, mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT) == nil\n}","handlingStrategy":"fallback","validationCode":"func vtInputSupported() bool {\n    var mode uint32\n    h := windows.Handle(os.Stdin.Fd())\n    if err := windows.GetConsoleMode(h, &mode); err != nil { return false }\n    ok := windows.SetConsoleMode(h, mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT) == nil\n    _ = windows.SetConsoleMode(h, mode) // restore\n    return ok\n}\n\nvar opts []tea.ProgramOption\nif !vtInputSupported() {\n    opts = append(opts, tea.WithoutRenderer())\n}\np := tea.NewProgram(model, opts...)","typeGuard":null,"tryCatchPattern":"if _, err := p.Run(); err != nil {\n    if strings.Contains(err.Error(), \"error setting console mode\") {\n        // ENABLE_VIRTUAL_TERMINAL_INPUT rejected: legacy console\n        log.Fatal(\"this console does not support VT input; use Windows Terminal or a ConPTY host\")\n    }\n    log.Fatalf(\"run: %v\", err)\n}","preventionTips":["Document Windows 10 1511+ (or Windows Terminal) as a runtime requirement for interactive mode.","Feature-detect VT input before starting and offer a non-rendering fallback path.","Never retry the same SetConsoleMode on a console that returned ERROR_INVALID_PARAMETER — the flag is unsupported, not transient."],"tags":["windows","console","vt-input","virtual-terminal","bubbletea","compatibility"],"backgroundTag":null,"analyzedSha":"351d2159f8d8a85613aa2a6e98c8c63df3c98623","analyzedAt":"2026-08-15T10:48:22.366Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}