junegunn/fzf · error
invalid preview window option: ${token}
Error message
invalid preview window option: ${token} What it means
Thrown by parsePreviewWindowImpl while tokenizing the --preview-window option. Each comma-separated token must match a known flag (hidden, nohidden, wrap, nowrap, cycle, border-*, down, up, left, right), a header spec (~N), a size (N or N%), or a scroll offset (+N, -N, +{n}, -/N); anything else lands in this default branch and is rejected after all regexes fail.
Source
Thrown at src/options.go:2419
case "nofollow":
opts.follow = false
case "info":
opts.info = true
case "noinfo":
opts.info = false
default:
if headerRegex.MatchString(token) {
if opts.headerLines, err = atoi(token[1:]); err != nil {
return err
}
} else if sizeRegex.MatchString(token) {
if opts.size, err = parseSize(token, 99, "window size"); err != nil {
return err
}
} else if offsetRegex.MatchString(token) {
opts.scroll = token
} else {
return errors.New("invalid preview window option: " + token)
}
}
}
if len(alternative) > 0 {
alternativeOpts := *opts
opts.alternative = &alternativeOpts
opts.alternative.hidden = false
opts.alternative.alternative = nil
err = parsePreviewWindowImpl(opts.alternative, alternative)
}
return err
}
func parseMargin(opt string, margin string) ([4]sizeSpec, error) {
margins := strings.Split(margin, ",")
checked := func(str string) (sizeSpec, error) {
return parseSize(str, 49, opt)
}View on GitHub (pinned to bd4efa277b)
Solutions
- Replace removed tokens: 'tight' -> drop it or use 'border-none'; 'nohtight' likewise
- Check the man page (fzf --man) for the current token list and fix typos
- Split multi-token specs into repeated --preview-window flags to isolate the bad token
Example fix
# before (fzf <= 0.20 style) fzf --preview-window right:50%:tight # after fzf --preview-window right:50%:border-none
Defensive patterns
Strategy: validation
Validate before calling
# bash: screen tokens against the known vocabulary
token_ok() {
[[ "$1" =~ ^(hidden|nohidden|wrap|nowrap|cycle|nocycle|up|down|left|right|border|border-rounded|border-square|border-bold|border-block|border-thinblock|border-double|noborder|border-sharp|border-horizontal|border-vertical|border-top|border-bottom|border-left|border-right|follow|nofollow)$ ]] ||
[[ "$1" =~ ^[0-9]+%?$ ]] || [[ "$1" =~ ^(\+\{-?[0-9]+|n\}|[+-][0-9]+|-?/[1-9][0-9]*)+$ ]] || [[ "$1" =~ ^~(0|[1-9][0-9]*)$ ]]
}
IFS=',' read -ra T <<< "$PW"; for t in "${T[@]}"; do token_ok "$t" || echo "bad token: $t" >&2; done Prevention
- After fzf upgrades, grep old configs for removed tokens like 'tight'
- Quote the whole --preview-window value so commas reach fzf intact
When it happens
Trigger: `--preview-window 'tight'` (old fzf token removed), `--preview-window 'right:60:xx'`, `--preview-window 'border-rounded,'` trailing garbage, or a mistyped size like '5O%' (letter O).
Common situations: Carrying over 'tight'/'nohtight' from fzf <= 0.20 configs where tight was valid — it was later replaced by 'border-none' behavior; version upgrades breaking old alias scripts; unquoted specs where the shell splits or expands tokens.
Related errors
- key name required
- bind action not specified: ${keys}
- ${label} must be non-negative
- ${label} (without %) must be a non-negative integer
- invalid ${opt}: ${margin}
AI-assisted analysis of junegunn/fzf@bd4efa277b (2026-08-15).
Data as JSON: /api/errors/3517866dd4e3e641.
Report an issue: GitHub.