charmbracelet/glow · error

unable to run tui program: %w

Error message

unable to run tui program: %w

What it means

The final step of the TUI path: ui.NewProgram(cfg, content).Run() starts a Bubble Tea program on the terminal. Errors come from the terminal I/O layer: no TTY available on stdin/stdout, TERM unset or set to a value without usable terminfo (e.g. dumb), failure opening /dev/tty, or renderer setup failing in non-interactive contexts. The underlying terminal error is wrapped with %w.

Source

Thrown at main.go:368

	if err != nil {
		return fmt.Errorf("error parsing config: %v", err)
	}

	// use style set in env, or auto if unset
	if err := validateStyle(cfg.GlamourStyle); err != nil {
		cfg.GlamourStyle = style
	}

	cfg.Path = path
	cfg.ShowAllFiles = showAllFiles
	cfg.ShowLineNumbers = showLineNumbers
	cfg.GlamourMaxWidth = width
	cfg.EnableMouse = mouse
	cfg.PreserveNewLines = preserveNewLines

	// Run Bubble Tea program
	if _, err := ui.NewProgram(cfg, content).Run(); err != nil {
		return fmt.Errorf("unable to run tui program: %w", err)
	}

	return nil
}

func main() {
	closer, err := setupLog()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	if err := rootCmd.Execute(); err != nil {
		_ = closer()
		os.Exit(1)
	}
	_ = closer()
}

View on GitHub (pinned to e3970c813d)

Solutions

  1. Run in a real terminal: use ssh -t for remote, docker exec -it for containers
  2. Set a valid TERM: export TERM=xterm-256color
  3. Bypass the TUI when piping: glow README.md | cat (static render path)
  4. Check the TERM spelling and that a terminfo entry exists: infocmp $TERM

Example fix

# before
ssh host "glow"              # no tty allocated
docker exec glow glow docs/readme.md

# after
ssh -t host "glow"
docker exec -it glow glow docs/readme.md
Defensive patterns

Strategy: try-catch

Validate before calling

func interactiveTerminal() bool {
	if term := os.Getenv("TERM"); term == "" || term == "dumb" { return false }
	fi, err := os.Stdout.Stat()
	if err != nil { return false }
	return fi.Mode()&os.ModeCharDevice != 0
}

Try / catch

if _, err := ui.NewProgram(cfg, content).Run(); err != nil {
	if !interactiveTerminal() {
		// no TTY: fall back to static rendering instead of failing
		return renderStatic(content, w)
	}
	return fmt.Errorf("unable to run tui program: %w", err)
}

Prevention

When it happens

Trigger: Running glow's TUI with stdout piped or redirected (not a character device); TERM unset or TERM=dumb; ssh without -t; docker exec without -it; terminfo database missing or TERM misspelt (xterm256color).

Common situations: CI pipelines invoking the TUI, docker exec/kubectl exec sessions without -it, cron-invoked runs, minimal containers without terminfo installed, Windows terminals lacking ANSI support.

Related errors


AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15). Data as JSON: /api/errors/b38ac4ed2beda361. Report an issue: GitHub.