{"record":{"id":"994734d5b16fcd99","repo":"junegunn/fzf","slug":"failed-to-open-s","errorCode":null,"errorMessage":"failed to open %s","messagePattern":"failed to open (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/tui/light_unix.go","lineNumber":64,"sourceCode":"func openTty(ttyDefault string, mode int) (*os.File, error) {\n\tvar in *os.File\n\tvar err error\n\tif len(ttyDefault) > 0 {\n\t\tin, err = os.OpenFile(ttyDefault, mode, 0)\n\t}\n\tif in == nil || err != nil || ttyDefault != DefaultTtyDevice && !util.IsTty(in) {\n\t\ttty := ttyname()\n\t\tif len(tty) > 0 {\n\t\t\tif in, err := os.OpenFile(tty, mode, 0); err == nil {\n\t\t\t\treturn in, nil\n\t\t\t}\n\t\t}\n\t\tif ttyDefault != DefaultTtyDevice {\n\t\t\tif in, err = os.OpenFile(DefaultTtyDevice, mode, 0); err == nil {\n\t\t\t\treturn in, nil\n\t\t\t}\n\t\t}\n\t\treturn nil, errors.New(\"failed to open \" + DefaultTtyDevice)\n\t}\n\treturn in, nil\n}\n\nfunc openTtyIn(ttyDefault string) (*os.File, error) {\n\treturn openTty(ttyDefault, syscall.O_RDONLY)\n}\n\nfunc openTtyOut(ttyDefault string) (*os.File, error) {\n\treturn openTty(ttyDefault, syscall.O_WRONLY)\n}\n\nfunc (r *LightRenderer) setupTerminal() {\n\tterm.MakeRaw(r.fd())\n}\n\nfunc (r *LightRenderer) restoreTerminal() {\n\tterm.Restore(r.fd(), r.origState)","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/junegunn/fzf/blob/bd4efa277b49ef34ca4025bff9b1a288e1980eff/src/tui/light_unix.go#L46-L82","documentation":"openTty failed to obtain a usable terminal device: the candidate input is not a TTY, and fallback opens of the controlling terminal name and /dev/tty both failed. fzf needs a real terminal for its interactive UI, so this aborts before rendering.","triggerScenarios":"openTtyIn/openTtyOut are called when stdin/stdout is redirected (pipe/file) and either ttyname() yields nothing, the named tty cannot be opened, or opening DefaultTtyDevice (/dev/tty) fails — typical when the process has no controlling terminal.","commonSituations":"Piping into fzf inside cron jobs, CI pipelines, or daemons where there is no controlling terminal; ssh -T sessions without tty allocation; minimal containers lacking /dev/tty.","solutions":["Allocate a TTY: run fzf in an interactive shell or use 'script -qec \"fzf\" /dev/null'","For non-interactive filtering use 'fzf --filter QUERY' which never opens the TUI","In ssh, enable allocation with 'ssh -t'"],"exampleFix":"# before (cron, no controlling terminal)\nfzf\n# after\nprintf 'a\\nb\\n' | fzf --filter a","handlingStrategy":"fallback","validationCode":"# ensure a controlling terminal or fall back to filter mode\nif ! [ -t 0 ] && ! [ -e /dev/tty ]; then\n  exec fzf --filter \"$QUERY\"\nfi\nfzf --query \"$QUERY\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use ssh -t for remote interactive sessions","In containers, run with -t (docker exec -it) so /dev/tty exists"],"tags":["fzf","terminal","tty","environment"],"backgroundTag":null,"analyzedSha":"bd4efa277b49ef34ca4025bff9b1a288e1980eff","analyzedAt":"2026-08-15T06:11:46.983Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}