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

  1. 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.
  2. 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.
  3. 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.
  4. 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

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


AI-assisted analysis of charmbracelet/bubbletea@351d2159f8 (2026-08-15). Data as JSON: /api/errors/5ae0ebbaa273fa25. Report an issue: GitHub.