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
- Run gum from a real terminal or wrap it in a pty (e.g. `script -qec 'gum filter ...' /dev/null`) when piping output.
- Check the wrapped error (`errors.Unwrap` / `%v`) to see whether the context was cancelled and extend or remove the deadline.
- If no TTY is available, avoid interactive filtering and use non-interactive alternatives (grep/fzf --filter, or a pre-computed selection).
- 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
- Only invoke gum filter when stdin/stdout are TTYs ([ -t 0 ] && [ -t 1 ]).
- Use a pty wrapper (script/unbuffer/expect) in scripts and CI.
- Set generous context deadlines when driving gum programmatically.
- Keep gum and Bubble Tea updated for TTY-detection fixes.
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
- not submitted
- failed to run input: %w
- unable to confirm: %w
- unable to pick selection: %w
- unable to pick selection: %w
AI-assisted analysis of charmbracelet/gum@4d089f9550 (2026-08-31).
Data as JSON: /api/errors/f9edbea25a62314d.
Report an issue: GitHub.