junegunn/fzf · error
unsupported key: ${key}
Error message
unsupported key: ${key} What it means
The last fallback in parseKeyChords: a comma-separated key list for --bind, --expect, --multi-bind etc. tokenizes each name into alt- combos, F1–F9 single-char forms, and single runes. Any token that is none of those — a multi-character name the switch above did not recognize — falls through to 'unsupported key: <key>'.
Source
Thrown at src/options.go:1314
switch r {
case escapedColon:
r = ':'
case escapedComma:
r = ','
case escapedPlus:
r = '+'
}
evt := tui.AltKey(r)
chords[evt] = key
list = append(list, evt)
} else if len(key) == 2 && strings.HasPrefix(lkey, "f") && key[1] >= '1' && key[1] <= '9' {
add(tui.EventType(tui.F1.Int() + int(key[1]) - '1'))
} else if len(runes) == 1 {
evt := tui.Key(runes[0])
chords[evt] = key
list = append(list, evt)
} else {
return nil, list, errors.New("unsupported key: " + key)
}
}
}
return chords, list, nil
}
func parseEveryEvent(arg string) (tui.Event, error) {
secs, err := strconv.ParseFloat(strings.TrimSpace(arg), 64)
if err != nil || math.IsNaN(secs) || math.IsInf(secs, 0) || secs <= 0 {
return tui.Event{}, errors.New("every() requires a positive number of seconds")
}
if secs < 0.01 {
secs = 0.01
}
ms := math.Round(secs * 1000)
if ms > math.MaxInt32 {
return tui.Event{}, errors.New("every() interval is too large")
}View on GitHub (pinned to bd4efa277b)
Solutions
- Consult fzf --help for the exact key names (ctrl-*, alt-*, f1-f12, shift-up/down, btab, tab, enter, space, bs, del, home, end, pgup, pgdn, up, down, left, right)
- Fix spelling: 'btab' not 'shift-tab', 'alt-z' not 'altz'
- Remove stray whitespace and empty tokens between commas
- Upgrade fzf if the key was added in a newer release (e.g. focus events in 0.35+)
Example fix
# before fzf --bind 'shift-tab:up' # after fzf --bind 'btab:up'
Defensive patterns
Strategy: validation
Validate before calling
KEYS='ctrl-a,btab,f3'
IFS=',' read -ra KS <<< "$KEYS"
for k in "${KS[@]}"; do
[[ "$k" =~ ^(ctrl|alt|shift)-(a-z|0-9|f1-f12|up|down|left|right|enter|space|tab|btab|del|home|end|pgup|pgdn|bs)$ ]] || { echo "unsupported key: $k" >&2; exit 1; }
done
fzf --bind "ctrl-a:accept" --expect "$KEYS" Type guard
isValidFzfKey() { [[ "$1" =~ ^(ctrl-|alt-|shift-)?[a-z0-9]+$ || "$1" =~ ^(f[1-9]|f1[0-2]|tab|btab|enter|space|bs|del|home|end|pgup|pgdn|up|down|left|right|left-click|right-click|scroll-up|scroll-down|double-click)$ ]]; } Prevention
- Diff your bind vocabulary against fzf --help after every upgrade
- Prefer canonical names (btab, not shift-tab; alt-z, not escape+z)
- Generate --bind lists from a validated key->action map instead of free-text strings
When it happens
Trigger: --bind 'ctrl-f2:...' style tokens not handled, unrecognized names like --expect 'ctrl-a,spacebar', 'home' on versions lacking it, 'shift-tab' written where 'btab' is expected, or key names with trailing whitespace from multiline --bind strings.
Common situations: Bind scripts targeting newer/older fzf key vocabularies (e.g. 'pos' or 'jump' actions vs keys); copy-pasted wiki examples for a different version; Windows/macOS terminal-specific names not portable to the Linux build.
Related errors
- invalid format: ${str}
- template should include at least 1 placeholder: ${str}
- invalid algorithm (expected: v1 or v2)
- invalid border style (expected: rounded|sharp|bold|block|thi
- every() requires a positive number of seconds
AI-assisted analysis of junegunn/fzf@bd4efa277b (2026-08-15).
Data as JSON: /api/errors/336571dbde1ffe37.
Report an issue: GitHub.