{"record":{"id":"4765a4199e6e188e","repo":"gitbutlerapp/gitbutler","slug":"interactive-mode-requested-but-there-is-no-terminal-to","errorCode":null,"errorMessage":"interactive mode requested, but there is no terminal to prompt on","messagePattern":"interactive mode requested, but there is no terminal to prompt on","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-installer/src/lib.rs","lineNumber":110,"sourceCode":"/// some of them would dispatch it to an unrelated `but-agent` executable on\n/// PATH, whereas `--help` is built in on every version.\nfn supports_agent_setup(but_path: &std::path::Path) -> bool {\n    std::process::Command::new(but_path)\n        .arg(\"--help\")\n        .stdin(std::process::Stdio::null())\n        .stderr(std::process::Stdio::null())\n        .output()\n        .is_ok_and(|out| {\n            out.status.success()\n                && String::from_utf8_lossy(&out.stdout)\n                    .lines()\n                    .any(|line| line.trim_start().starts_with(\"agent \"))\n        })\n}\n\nfn run_installation_impl(config: InstallerConfig, interactive: bool) -> Result<()> {\n    if interactive && !ui::is_connected_to_terminal() {\n        anyhow::bail!(\"interactive mode requested, but there is no terminal to prompt on\");\n    }\n\n    info(&format!(\"Detected platform: {}\", config.platform));\n\n    // Fetch release information\n    let message = match &config.version_request {\n        VersionRequest::Nightly => \"Fetching latest nightly release information...\",\n        VersionRequest::Specific(_) => \"Fetching release information...\",\n        VersionRequest::Release => \"Fetching latest release information...\",\n    };\n    info(message);\n\n    let release = fetch_release(&config)?;\n\n    // Display version information\n    let channel = match &config.version_request {\n        VersionRequest::Nightly => {\n            info(&format!(","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-installer/src/lib.rs#L92-L128","documentation":"run_installation_impl refuses to run when interactive mode was requested but stdin/stdout is not attached to a TTY, since prompting the user would hang or fail. It is a guard ensuring prompts (and later shell configuration) always have a real terminal.","triggerScenarios":"Calling run_installation/run_installation_with_version with interactive=true from a non-TTY context: CI pipeline, cron job, piped/redirected output, daemon, or embedded invocation.","commonSituations":"Running the installer in CI (GitHub Actions, Docker build) with an interactive flag set by default, piping installer output to a file or another command, running under a process supervisor without a PTY.","solutions":["Run without interactive mode (interactive=false) so defaults are used non-interactively","Run inside a real terminal (or use `script`/PTY wrapper in CI)","Remove pipes/redirects on stdin/stdout when invoking the installer","Pre-configure settings via flags/env so no prompting is needed"],"exampleFix":"// before\nrun_installation(config, /* interactive */ true)?;\n// after\nlet interactive = std::io::stdin().is_terminal();\nrun_installation(config, interactive)?;","handlingStrategy":"validation","validationCode":"let can_prompt = std::io::stdin().is_terminal() && std::io::stdout().is_terminal();\nif !can_prompt { /* run non-interactively or abort early */ }","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"no terminal to prompt on\") => {\n        // fall back to non-interactive mode with defaults\n    }\n    other => other?,\n}","preventionTips":["Detect TTY availability before requesting interactive mode","In CI, always use non-interactive flags","Avoid piping stdin/stdout when prompts are expected","Provide config via flags/env to avoid needing prompts"],"tags":["terminal","tty","interactive","cli"],"backgroundTag":"unsupported-operation","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}