Skip to content

fzf Footguns

Mistakes that cause wrong selections, lost data, or broken shell configurations.


1. Piping fzf output directly to destructive commands

You run fd -t f | fzf -m | xargs rm. You accidentally press Enter with the wrong file selected. It is deleted instantly. No confirmation, no undo, no recycle bin.

Fix: Add -p to xargs for confirmation: | xargs -p rm. Or pipe through echo first to preview: | xargs echo rm. For critical operations, use rm -i instead of rm.


2. Using find instead of fd as FZF_DEFAULT_COMMAND

You leave FZF_DEFAULT_COMMAND unset. fzf falls back to find. In a large repo, Ctrl-T takes 10+ seconds. .git objects, node_modules, and binary files clog the results.

Fix: Set FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'. fd is 5-10x faster, respects .gitignore, and produces cleaner results.


3. Forgetting --header-lines with tabular input

You pipe kubectl get pods into fzf. The header row (NAME READY STATUS...) is a selectable item. You select it, and the downstream command receives a header string instead of a pod name.

Fix: Use fzf --header-lines=1 to pin the first line as a non-selectable header. This works for any tabular command output (ps, docker ps, kubectl get).


4. Not using --ansi with colored output

You pipe rg --color=always into fzf. Without --ansi, fzf displays raw ANSI escape codes as literal characters: ^[[31mERROR^[[0m. The output is unreadable and the fuzzy matching breaks.

Fix: Always use fzf --ansi when piping colored output. Conversely, do not use --ansi with uncolored output — it adds unnecessary processing overhead.


5. fzf returning empty string on Escape/Ctrl-C

You run cd $(fd -t d | fzf). The user presses Escape to cancel. fzf returns an empty string. The command becomes cd "", which changes to $HOME. You are silently teleported to a different directory.

Fix: Capture the output and check it: dir=$(fd -t d | fzf) && cd "${dir}". The && ensures cd only runs if fzf returned a selection (exit code 0). fzf returns exit code 130 on Ctrl-C and 1 on no match.


6. Multi-select mode when you meant single-select

You run kubectl get pods -o name | fzf -m and press Tab on several pods without realizing it. The downstream command receives multiple arguments. kubectl exec -it fails because it only accepts one pod.

Fix: Only use -m (multi-select) when the downstream command handles multiple arguments. For commands that take one input, omit -m. If in doubt, default to single-select.


7. Wrong delimiter with --preview

You use rg -n "error" | fzf --preview 'bat {1}' expecting {1} to be the filename. But fzf's default delimiter is any whitespace, not :. {1} captures something unexpected and the preview shows nothing.

Fix: Set the delimiter explicitly: fzf --delimiter=: --preview 'bat {1}'. Then {1} is the filename, {2} is the line number (for rg output format file:line:content).


8. Shell integration overriding existing keybindings

You add eval "$(fzf --bash)" to your .bashrc. It overwrites your existing Ctrl-R (history search), Ctrl-T (transpose), and Alt-C bindings. Your custom shell keybindings stop working.

Fix: Check your existing bindings before enabling fzf shell integration. If you only want Ctrl-R replacement, source only the key-bindings file. If you want to keep existing bindings, set fzf to use different keys via FZF_CTRL_T_COMMAND etc.


9. Preview command errors flooding stderr

Your fzf preview command fails on some items (e.g., bat on a binary file). Error messages flash in the preview window and obscure useful output.

Fix: Redirect stderr in the preview command: --preview 'bat --color=always {} 2>/dev/null || echo "Binary or unreadable file"'. Always provide a fallback for preview errors.


10. Not quoting fzf output in shell commands

You run vim $(fzf). A selected file has a space in its name: error log.txt. Without quotes, vim opens two files: error and log.txt. Neither exists.

Fix: Always quote: vim "$(fzf)". Or use xargs with null separation: fzf --print0 | xargs -0 vim. This applies to any command that consumes fzf output.