{"record":{"id":"5a5a8c4b0549fcf8","repo":"nikivdev/code","slug":"requires-an-interactive-terminal-tty-run","errorCode":null,"errorMessage":"{} {} requires an interactive terminal (TTY); run this in a terminal tab (e.g. Zed/Ghostty)","messagePattern":"(.+?) (.+?) requires an interactive terminal \\(TTY\\); run this in a terminal tab \\(e\\.g\\. Zed/Ghostty\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ai.rs","lineNumber":5183,"sourceCode":"    connect_event.source = Some(\"codex-connect\".to_string());\n    let _ = activity_log::append_daily_event(connect_event);\n}\n\nfn provider_name(provider: Provider) -> &'static str {\n    match provider {\n        Provider::Claude => \"claude\",\n        Provider::Codex => \"codex\",\n        Provider::Cursor => \"cursor\",\n        Provider::All => \"ai\",\n    }\n}\n\nfn ensure_provider_tty(provider: Provider, action: &str) -> Result<()> {\n    if io::stdin().is_terminal() && io::stdout().is_terminal() {\n        return Ok(());\n    }\n\n    bail!(\n        \"{} {} requires an interactive terminal (TTY); run this in a terminal tab (e.g. Zed/Ghostty)\",\n        provider_name(provider),\n        action\n    );\n}\n\nfn print_provider_session_listing(\n    provider: Provider,\n    target: &Path,\n    sessions: &[AiSession],\n    json: bool,\n) -> Result<()> {\n    if sessions.is_empty() {\n        let provider_name = match provider {\n            Provider::Claude => \"Claude\",\n            Provider::Codex => \"Codex\",\n            Provider::Cursor => \"Cursor\",\n            Provider::All => \"AI\",","sourceCodeStart":5165,"sourceCodeEnd":5201,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ai.rs#L5165-L5201","documentation":"This error is thrown by ensure_provider_tty in src/ai.rs:5183 when an AI provider subcommand (such as browse or continue) that requires interactivity is run while stdin or stdout is not a TTY. Provider CLIs like Claude and Codex drive interactive pickers/REPLs, which cannot run when input/output is piped, redirected, or spawned without a terminal. The library bails early with a clear message naming the provider and action rather than letting the underlying CLI fail cryptically.","triggerScenarios":"Running `f ai claude browse` or `f ai codex continue` (via ensure_provider_tty) when io::stdin().is_terminal() or io::stdout().is_terminal() returns false — e.g. piping output (`| grep`), redirecting (`> file`), running under a non-interactive CI job, or invoking from an editor task without a terminal tab.","commonSituations":"Running the command from a CI pipeline or cron job; invoking it from an editor-integrated task runner (Zed task, VS Code terminal panel configured as output-only); piping the picker output to jq/grep; running via SSH without `-t`; wrapping in scripts that capture stdout.","solutions":["Run the command directly in an interactive terminal tab (e.g. Zed/Ghostty terminal, not a task/output panel)","Remove any pipe or output redirection so both stdin and stdout are terminals","Use `ssh -t` when remoting so a pseudo-terminal is allocated","If automation is the goal, use a non-interactive subcommand (e.g. `f ai codex sessions` with explicit path/query) instead of browse/continue"],"exampleFix":"// before (piped, fails)\n$ f ai codex browse | head -n 5\n// after (run interactively)\n$ f ai codex browse","handlingStrategy":"validation","validationCode":"use std::io::IsTerminal;\nfn can_run_interactive() -> bool {\n    std::io::stdin().is_terminal() && std::io::stdout().is_terminal()\n}\nif !can_run_interactive() {\n    eprintln!(\"Run `f ai ... browse/continue` in a real terminal tab.\");\n    return;\n}","typeGuard":"fn is_tty() -> bool {\n    use std::io::IsTerminal;\n    std::io::stdin().is_terminal() && std::io::stdout().is_terminal()\n}","tryCatchPattern":"match ensure_provider_tty(provider, \"browse\") {\n    Ok(()) => { /* launch picker */ }\n    Err(e) => eprintln!(\"{e}; open a terminal tab and rerun interactively\"),\n}","preventionTips":["Run interactive subcommands directly in a terminal tab, not editor task/output panels","Never pipe or redirect stdout of browse/continue","For automation use non-interactive subcommands like `sessions`","Over SSH use `ssh -t` to allocate a TTY"],"tags":["cli","tty","interactive-terminal"],"backgroundTag":"missing-tty-interactive-terminal-required","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}