charmbracelet/gum · error

unable to run filter: %w

Error message

unable to run filter: %w

What it means

gum filter wraps the Bubble Tea program loop for its interactive fuzzy-filter picker. If `tea.NewProgram(...).Run()` returns an error (renderer/TTY failure, context cancellation, I/O error writing to the output), Run returns it wrapped with `unable to run filter: %w`. This means the interactive UI never completed, not that the user failed to pick an item (that is the separate "nothing selected" error).

Source

Thrown at filter/command.go:148

	currentSelected := 0
	if len(o.Selected) > 0 {
		for i, option := range matches {
			if currentSelected >= o.Limit || (!isSelectAll && !slices.Contains(o.Selected, option.Str)) {
				continue
			}
			if o.Limit == 1 {
				m.cursor = i
				m.selected[option.Str] = struct{}{}
			} else {
				currentSelected++
				m.selected[option.Str] = struct{}{}
			}
		}
	}

	tm, err := tea.NewProgram(m, options...).Run()
	if err != nil {
		return fmt.Errorf("unable to run filter: %w", err)
	}

	m = tm.(model)
	if !m.submitted {
		return errors.New("nothing selected")
	}

	// allSelections contains values only if limit is greater
	// than 1 or if flag --no-limit is passed, hence there is
	// no need to further checks
	if len(m.selected) > 0 {
		o.checkSelected(m)
	} else if len(m.matches) > m.cursor && m.cursor >= 0 {
		tty.Println(m.matches[m.cursor].Str)
	}

	return nil
}

View on GitHub (pinned to 4d089f9550)

Solutions

  1. Run gum from a real terminal or wrap it in a pty (e.g. `script -qec 'gum filter ...' /dev/null`) when piping output.
  2. Check the wrapped error (`errors.Unwrap` / `%v`) to see whether the context was cancelled and extend or remove the deadline.
  3. If no TTY is available, avoid interactive filtering and use non-interactive alternatives (grep/fzf --filter, or a pre-computed selection).
  4. Update gum/Bubble Tea to the latest versions — older releases had TTY-detection bugs in non-interactive environments.

Example fix

// before
cmd := exec.Command("gum", "filter", "one", "two")
out, err := cmd.Output() // fails in non-TTY environment
// after
cmd := exec.Command("script", "-qec", "gum filter one two", "/dev/null")
out, err := cmd.Output() // allocate a pty so the TUI can run
Defensive patterns

Strategy: fallback

Validate before calling

if [ -t 0 ] && [ -t 1 ]; then
  selection=$(gum filter "${items[@]}")
else
  echo "interactive TTY required; using first item" >&2
  selection="${items[0]}"
fi

Try / catch

if ! selection=$(gum filter "${items[@]}"); then
  echo "filter failed: $selection" >&2
  selection="${items[0]}" # fallback
fi

Prevention

When it happens

Trigger: Running `gum filter` when stdout/stderr is not a TTY (piped/captured output without a pty), a context passed to the program is cancelled before the user selects, or the Bubble Tea program fails to start its input/output renderer.

Common situations: CI pipelines or scripts that capture gum output through pipes; automation that sets a short context deadline and cancels while the filter is open; terminal emulators or environments where gum cannot detect terminal size.

Related errors


AI-assisted analysis of charmbracelet/gum@4d089f9550 (2026-08-31). Data as JSON: /api/errors/f9edbea25a62314d. Report an issue: GitHub.