{"record":{"id":"e8222c5f836c7956","repo":"nikivdev/code","slug":"no-session-specified-interactive-selection-requir","errorCode":null,"errorMessage":"no session specified (interactive selection requires a TTY)","messagePattern":"no session specified \\(interactive selection requires a TTY\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ai.rs","lineNumber":13323,"sourceCode":"        }\n    }\n\n    let index = load_index()?;\n    let sessions = read_sessions_for_project(provider)?;\n\n    if sessions.is_empty() && session.is_none() {\n        let provider_name = match provider {\n            Provider::Claude => \"Claude\",\n            Provider::Codex => \"Codex\",\n            Provider::Cursor => \"Cursor\",\n            Provider::All => \"AI\",\n        };\n        println!(\"No {} sessions found for this project.\", provider_name);\n        return Ok(());\n    }\n\n    if session.is_none() && !io::stdin().is_terminal() {\n        bail!(\"no session specified (interactive selection requires a TTY)\");\n    }\n\n    // Find the session ID and provider\n    let (session_id, session_provider) = if let Some(ref query) = session {\n        resolve_session_selection(query, &sessions, &index, provider)?\n    } else {\n        // Show fzf selection\n        let mut entries: Vec<FzfSessionEntry> = Vec::new();\n\n        for session in &sessions {\n            if session.timestamp.is_none()\n                && session.last_message_at.is_none()\n                && session.last_message.is_none()\n                && session.first_message.is_none()\n                && session.error_summary.is_none()\n            {\n                continue;\n            }","sourceCodeStart":13305,"sourceCodeEnd":13341,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ai.rs#L13305-L13341","documentation":"The session open command supports interactive selection when no explicit session argument is given, but only when stdin is a TTY. If no session was specified and stdin is not a terminal (CI, piped input, background job), interactive selection is impossible, so the command bails.","triggerScenarios":"Running `f codex open` (or equivalent) with no session argument while stdin is redirected/piped — e.g. in CI pipelines, scripts, `cargo run < file`, or non-interactive shells.","commonSituations":"CI jobs invoking the CLI without a session ID; shell scripts piping into the command; running under a process manager or IDE terminal without TTY allocation.","solutions":["Pass an explicit session ID/query argument so selection isn't needed","Allocate a TTY (run in an interactive terminal, or `script -qc` / `ssh -t`)","List sessions first (`f codex sessions`) and script the choice explicitly"],"exampleFix":"// before\nCI_JOB=1 f codex open   # no TTY -> bail\n// after\nf codex open \"$(f codex sessions --latest-id)\"","handlingStrategy":"validation","validationCode":"if session_arg.is_none() && !atty::is(atty::Stream::Stdin) {\n    eprintln!(\"no session specified (interactive selection requires a TTY)\");\n    std::process::exit(2);\n}","typeGuard":"fn needs_explicit_session(session: &Option<String>, stdin_tty: bool) -> bool {\n    session.is_none() && !stdin_tty\n}","tryCatchPattern":null,"preventionTips":["Always pass an explicit session ID in scripts/CI","Use `script -qc` or `ssh -t` when interactive selection is unavoidable","Resolve the session via `sessions --json` instead of relying on prompts"],"tags":["tty","interactive","cli","non-interactive"],"backgroundTag":"requires-tty","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}