{"record":{"id":"64634a5969b31f42","repo":"junegunn/fzf","slug":"invalid-popup-option-arg-expected-center-to","errorCode":null,"errorMessage":"invalid popup option: ${arg} (expected: [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]][,border-native])","messagePattern":"invalid popup option: (.+?) \\(expected: \\[center\\|top\\|bottom\\|left\\|right\\]\\[,SIZE\\[%\\]\\]\\[,SIZE\\[%\\]\\]\\[,border-native\\]\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/options.go","lineNumber":430,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\treturn shape\n}\n\nfunc defaultTmuxOptions(index int) *tmuxOptions {\n\treturn &tmuxOptions{\n\t\tposition: posCenter,\n\t\twidth:    sizeSpec{50, true},\n\t\theight:   sizeSpec{50, true},\n\t\tindex:    index}\n}\n\nfunc parseTmuxOptions(arg string, index int) (*tmuxOptions, error) {\n\tvar err error\n\topts := defaultTmuxOptions(index)\n\ttokens := splitRegexp.Split(arg, -1)\n\terrorToReturn := errors.New(\"invalid popup option: \" + arg + \" (expected: [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]][,border-native])\")\n\tif len(tokens) == 0 || len(tokens) > 4 {\n\t\treturn nil, errorToReturn\n\t}\n\n\tfor i, token := range tokens {\n\t\tif token == \"border-native\" {\n\t\t\ttokens = append(tokens[:i], tokens[i+1:]...) // cut the 'border-native' option\n\t\t\topts.border = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Defaults to 'center'\n\tfirst := \"center\"\n\tif len(tokens) > 0 {\n\t\tfirst = tokens[0]\n\t}\n","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/junegunn/fzf/blob/bd4efa277b49ef34ca4025bff9b1a288e1980eff/src/options.go#L412-L448","documentation":"Returned by startHttpServer (src/server.go:109) when net.Listen('tcp', host:port) fails while starting fzf's --listen TCP server. This is the standard bind failure for fzf's server mode: the address cannot be bound because another process owns the port, the port is privileged, or the host part cannot resolve/bind. The OS error is flattened into the formatted message, so check the port separately.","triggerScenarios":"Running fzf --listen PORT (or host:PORT) when another process already binds that TCP port (another fzf server, a web app, anything); using a port < 1024 as a non-root user; specifying a host in the --listen address that does not correspond to a local interface (e.g. --listen 203.0.113.5:6266); or the ephemeral/accepted-connection state keeping a port reserved (SO_REUSEADDR is not set, TIME_WAIT). Note: binding a non-local host additionally requires FZF_API_KEY to be set (checked earlier at src/server.go:85-87).","commonSituations":"Two fzf instances configured with the same fixed --listen port in shell rc files or editor plugins; choosing a port already used by a dev server (3000, 8080...); Linux net.ipv4.ip_unprivileged_port_start restrictions for low ports; typo'd host in the listen address; containers where the requested port is already mapped by another process.","solutions":["Find what holds the port and stop it or pick another: `ss -ltnp 'sport = :6266'` or `lsof -iTCP:6266 -sTCP:LISTEN`, then kill that process or rerun fzf with a free port.","Use --listen 0 to let the kernel assign a free ephemeral port; fzf reports the chosen port via the shell integration ($FZF_PORT) so a fixed port is often unnecessary.","If a low port (<1024) is required, run with elevated privileges or pick a port above net.ipv4.ip_unprivileged_port_start.","Verify the host part of the address is a local IP/hostname of this machine (`ip addr`); use localhost or omit the host for loopback-only listening.","Ensure FZF_API_KEY is set when binding a non-local address, otherwise you will hit the earlier 'FZF_API_KEY is required' error first."],"exampleFix":"# before\nfzf --listen 6266   # port already bound by a previous fzf\n\n# after\n# option A: kill the previous listener\nkill $(lsof -t -iTCP:6266 -sTCP:LISTEN)\nfzf --listen 6266\n\n# option B: let fzf pick a free port (shell integration exports $FZF_PORT)\nfzf --listen 0","handlingStrategy":"validation","validationCode":"// Go caller: check the TCP port is free before spawning fzf\nfunc portAvailable(host string, port int) bool {\n    if port == 0 {\n        return true // ephemeral, kernel picks\n    }\n    ln, err := net.Listen(\"tcp\", net.JoinHostPort(host, strconv.Itoa(port)))\n    if err != nil {\n        return false\n    }\n    ln.Close()\n    return true\n}\n\nif !portAvailable(\"localhost\", 6266) {\n    // choose another port or use --listen 0\n}","typeGuard":"func isTcpListenFailure(stderr string) bool {\n    return strings.Contains(stderr, \"failed to listen on \") &&\n        !strings.Contains(stderr, \".sock\")\n}","tryCatchPattern":"// shell: retry on a fresh port when the fixed port is taken\nfzf --listen 6266 2>err.log || {\n    grep -q \"failed to listen on\" err.log && exec fzf --listen 0\n}","preventionTips":["Prefer --listen 0 and read the assigned port from fzf's shell integration ($FZF_PORT) instead of hardcoding ports.","Pick ports from the dynamic/ephemeral or private ranges (49152-65535) to dodge dev servers.","In long-lived integrations, health-check and restart the fzf server; kill it on EXIT to release the port."],"tags":["go","tcp","fzf","server","port-conflict"],"backgroundTag":null,"analyzedSha":"bd4efa277b49ef34ca4025bff9b1a288e1980eff","analyzedAt":"2026-08-15T06:11:46.983Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}