getzola/zola · warning

unable to read from stdin for confirmation

Error message

unable to read from stdin for confirmation

What it means

read_line in src/prompt.rs reads a single line from stdin to confirm an interactive prompt. It panics/aborts with this anyhow error when stdin yields no line at all — i.e. the stream is closed (EOF) or the read fails with an I/O error. The library throws it because a confirmation prompt cannot proceed without user input.

Source

Thrown at src/prompt.rs:15

use std::io::{self, BufRead, Write};

use url::Url;

use errors::{Result, anyhow};

/// Wait for user input and return what they typed
fn read_line() -> Result<String> {
    let stdin = io::stdin();
    let stdin = stdin.lock();
    let mut lines = stdin.lines();
    lines
        .next()
        .and_then(|l| l.ok())
        .ok_or_else(|| anyhow!("unable to read from stdin for confirmation"))
}

/// Ask a yes/no question to the user
pub fn ask_bool(question: &str, default: bool) -> Result<bool> {
    print!("{} {}: ", question, if default { "[Y/n]" } else { "[y/N]" });
    let _ = io::stdout().flush();
    let input = read_line()?;

    match &*input {
        "y" | "Y" | "yes" | "YES" | "true" => Ok(true),
        "n" | "N" | "no" | "NO" | "false" => Ok(false),
        "" => Ok(default),
        _ => {
            println!("Invalid choice: '{input}'");
            ask_bool(question, default)
        }
    }
}

View on GitHub (pinned to 61d3082821)

Solutions

  1. Provide input on stdin (pipe a line such as 'y' or run interactively) so lines().next() returns Some.
  2. Check for a non-interactive flag (e.g. --force / --yes) to skip confirmation prompts entirely.
  3. In CI, use the tool's non-interactive mode instead of relying on a TTY prompt.
  4. If embedding, ensure stdin is not closed/consumed before the prompt runs.

Example fix

// before
echo -n | myapp deploy   # stdin at EOF -> error
// after
yes | myapp deploy       # or: myapp deploy --yes
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: probe stdin before prompting
use std::io::IsTerminal;
fn stdin_usable() -> bool { !std::io::stdin().is_terminal() || atty_ok() } // or check !stdin is at EOF via a peek
if std::io::stdin().read_line(&mut probe).is_ok() && !probe.is_empty() { /* safe to prompt */ }

Type guard

fn stdin_has_input() -> bool {
    use std::io::IsTerminal;
    std::io::stdin().is_terminal() // false in CI/piped-EOF contexts -> skip prompting
}

Try / catch

match ask_bool("continue?", true) {
    Ok(v) => /* proceed with v */,
    Err(e) if e.to_string().contains("unable to read from stdin") => /* assume default / skip prompt */,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling ask_bool or ask_url when stdin is closed, exhausted (e.g. stdin already consumed to EOF by an earlier read or piped input), or the underlying read returns an I/O error.

Common situations: Running the CLI non-interactively (CI pipelines, cron) with stdin at EOF or </dev/null; piping input that runs out of lines before the prompt; a terminal/PTY that detaches mid-run.

Related errors


AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03). Data as JSON: /api/errors/0af5da855ad6d887. Report an issue: GitHub.