charmbracelet/bubbletea · error
error setting console mode: %w
Error message
error setting console mode: %w
What it means
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.
Source
Thrown at tty_windows.go:31
func (p *Program) initInput() (err error) {
// Save stdin state and enable VT input
// We also need to enable VT
// input here.
if f, ok := p.input.(term.File); ok && term.IsTerminal(f.Fd()) {
p.ttyInput = f
p.previousTtyInputState, err = term.MakeRaw(p.ttyInput.Fd())
if err != nil {
return fmt.Errorf("error making terminal raw: %w", err)
}
// Enable VT input
var mode uint32
if err := windows.GetConsoleMode(windows.Handle(p.ttyInput.Fd()), &mode); err != nil {
return fmt.Errorf("error getting console mode: %w", err)
}
if err := windows.SetConsoleMode(windows.Handle(p.ttyInput.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil {
return fmt.Errorf("error setting console mode: %w", err)
}
}
// Save output screen buffer state and enable VT processing.
if f, ok := p.output.(term.File); ok && term.IsTerminal(f.Fd()) {
p.ttyOutput = f
p.previousOutputState, err = term.GetState(f.Fd())
if err != nil {
return fmt.Errorf("error getting terminal state: %w", err)
}
var mode uint32
if err := windows.GetConsoleMode(windows.Handle(p.ttyOutput.Fd()), &mode); err != nil {
return fmt.Errorf("error getting console mode: %w", err)
}
if err := windows.SetConsoleMode(windows.Handle(p.ttyOutput.Fd()),
mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING|View on GitHub (pinned to 351d2159f8)
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.
Example fix
// before
p := tea.NewProgram(model{})
if _, err := p.Run(); err != nil {
log.Fatalf("%v", err) // error setting console mode: The parameter is incorrect
}
// after: probe VT support, degrade gracefully
if !vtInputSupported() {
p = tea.NewProgram(model{}, tea.WithoutRenderer())
}
if _, err := p.Run(); err != nil { log.Fatal(err) }
func vtInputSupported() bool {
var mode uint32
h := windows.Handle(os.Stdin.Fd())
if err := windows.GetConsoleMode(h, &mode); err != nil { return false }
return windows.SetConsoleMode(h, mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT) == nil
} Defensive patterns
Strategy: fallback
Validate before calling
func vtInputSupported() bool {
var mode uint32
h := windows.Handle(os.Stdin.Fd())
if err := windows.GetConsoleMode(h, &mode); err != nil { return false }
ok := windows.SetConsoleMode(h, mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT) == nil
_ = windows.SetConsoleMode(h, mode) // restore
return ok
}
var opts []tea.ProgramOption
if !vtInputSupported() {
opts = append(opts, tea.WithoutRenderer())
}
p := tea.NewProgram(model, opts...) Try / catch
if _, err := p.Run(); err != nil {
if strings.Contains(err.Error(), "error setting console mode") {
// ENABLE_VIRTUAL_TERMINAL_INPUT rejected: legacy console
log.Fatal("this console does not support VT input; use Windows Terminal or a ConPTY host")
}
log.Fatalf("run: %v", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- error making terminal raw: %w
- error getting console mode: %w
- error getting terminal state: %w
- program experienced a panic
- program was killed
AI-assisted analysis of charmbracelet/bubbletea@351d2159f8 (2026-08-15).
Data as JSON: /api/errors/5ae0ebbaa273fa25.
Report an issue: GitHub.