{"record":{"id":"a1a4354f9ef8d432","repo":"junegunn/fzf","slug":"label-must-be-non-negative","errorCode":null,"errorMessage":"${label} must be non-negative","messagePattern":"(.+?) must be non-negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/options.go","lineNumber":2236,"sourceCode":"\treturn nil\n}\n\nfunc strLines(str string) []string {\n\treturn strings.Split(strings.TrimSuffix(str, \"\\n\"), \"\\n\")\n}\n\nfunc parseSize(str string, maxPercent float64, label string) (sizeSpec, error) {\n\tvar spec = sizeSpec{}\n\tvar val float64\n\tvar err error\n\tpercent := strings.HasSuffix(str, \"%\")\n\tif percent {\n\t\tif val, err = atof(str[:len(str)-1]); err != nil {\n\t\t\treturn spec, err\n\t\t}\n\n\t\tif val < 0 {\n\t\t\treturn spec, errors.New(label + \" must be non-negative\")\n\t\t}\n\t\tif val > maxPercent {\n\t\t\treturn spec, fmt.Errorf(\"%s too large (max: %d%%)\", label, int(maxPercent))\n\t\t}\n\t} else {\n\t\tif strings.Contains(str, \".\") {\n\t\t\treturn spec, errors.New(label + \" (without %) must be a non-negative integer\")\n\t\t}\n\n\t\ti, err := atoi(str)\n\t\tif err != nil {\n\t\t\treturn spec, err\n\t\t}\n\t\tval = float64(i)\n\t\tif val < 0 {\n\t\t\treturn spec, errors.New(label + \" must be non-negative\")\n\t\t}\n\t}","sourceCodeStart":2218,"sourceCodeEnd":2254,"githubUrl":"https://github.com/junegunn/fzf/blob/bd4efa277b49ef34ca4025bff9b1a288e1980eff/src/options.go#L2218-L2254","documentation":"Thrown by parseSize when a percentage value is negative. Several size-like options (height, min-height as percentages, preview window size, margins, padding) accept either an absolute integer or a 'NN%' form; the percent branch parses the number with atof and rejects values below zero before even checking the per-option maximum.","triggerScenarios":"`--height '-50%'`, `--preview-window '-20%'`, `--margin '-1%,...'`, `--min-height '-5%'` — any percent spec where the numeric part is negative.","commonSituations":"Scripts computing a height percentage from terminal lines that can go negative on tiny terminals; shell arithmetic like \"$((${LINES}/2-40))%\" producing a minus sign; unquoted minus being interpreted as an option flag.","solutions":["Clamp computed percentages to >= 0 before passing them (e.g. use a max(0, x) helper in shell)","Quote the argument so '-20%' is not swallowed as a flag: `--height='-20%'` still errors but '--height' '-20' style mistakes become visible","Use absolute sizes instead of percentages when the source value can legitimately be small"],"exampleFix":"# before\nfzf --height \"$((${LINES}-60))%\"\n# after\nH=$((LINES-60)); [ \"$H\" -lt 0 ] && H=0\nfzf --height \"${H}%\"","handlingStrategy":"validation","validationCode":"# bash: percent sizes must be >= 0\npct_ok() { [[ \"$1\" =~ ^-?[0-9]+%$ ]] || return 0; [[ \"$1\" =~ ^- ]] && return 1 || return 0; }\npct_ok \"$HEIGHT\" || { echo \"negative percent\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp all computed percentages with a max(0, x) helper","Test option-building scripts inside a tiny terminal (stty rows 5) to catch underflow"],"tags":["fzf","go","cli","size","parsing"],"backgroundTag":null,"analyzedSha":"bd4efa277b49ef34ca4025bff9b1a288e1980eff","analyzedAt":"2026-08-15T06:11:46.983Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}