coding-horror/basic-computer-games · warning

Failed to flush to stdout.

Error message

Failed to flush to stdout.

What it means

A panic via .expect("Failed to flush to stdout.") on stdout().flush() at the top of the input loop in get_number_from_user_input() of the Blackjack Rust port. flush returns Err when stdout cannot be written (closed stdout, broken pipe, disk full on redirect). Because a print! without newline needs a flush before read_line, this call ensures the prompt appears; on flush failure it panics.

Source

Thrown at 10_Blackjack/rust/src/main.rs:570

    NOTE:'/' (splitting) is not currently implemented, and does nothing

    PRESS ENTER TO CONTINUE
    ");
    io::stdin().read_line(&mut String::new()).expect("Failed to read line");
}

/**
 * gets a usize integer from user input
 */
fn get_number_from_user_input(prompt: &str, min:usize, max:usize) -> usize {
    //input loop
    return loop {
        let mut raw_input = String::new(); // temporary variable for user input that can be parsed later

        //print prompt
        println!("{}", prompt);
        stdout().flush().expect("Failed to flush to stdout.");
        //read user input from standard input, and store it to raw_input
        //raw_input.clear(); //clear input
        io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");

        //from input, try to read a number
        match raw_input.trim().parse::<usize>() {
            Ok(i) => {
                if i < min || i > max { //input out of desired range
                    println!("INPUT OUT OF VALID RANGE.  TRY AGAIN.  {}-{}",min,max);
                    continue; // run the loop again
                }
                else {
                    break i;// this escapes the loop, returning i
                }
            },
            Err(e) => {
                println!("INVALID INPUT.  TRY AGAIN.  {}", e.to_string().to_uppercase());
                continue; // run the loop again

View on GitHub (pinned to 5301155192)

Solutions

  1. Avoid piping stdout to a tool that closes the pipe before the game finishes; run interactively or log to a file with adequate space.
  2. Replace .expect with `let _ = stdout().flush();` to tolerate flush failure.
  3. If scripting, ensure the downstream consumer reads all output.

Example fix

// before
stdout().flush().expect("Failed to flush to stdout.");

// after
let _ = stdout().flush();
Defensive patterns

Strategy: fallback

Validate before calling

// Avoid piping stdout through an early-closing consumer; check writability is unnecessary if you discard the flush result.

Try / catch

// Tolerate flush failure (broken pipe) instead of panicking
let _ = stdout().flush();
// or handle SIGPIPE/BrokenPipe explicitly:
match stdout().flush() { Ok(_) => {}, Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => std::process::exit(0), Err(_) => {} }

Prevention

When it happens

Trigger: stdout is closed or piped to a consumer that exited (SIGPIPE/broken pipe); redirecting output to a full disk or unwritable file; running under a harness that closes stdout.

Common situations: Piping the program's output to `head` which closes the pipe early; redirecting to a filesystem that fills up; a wrapper that closes stdout prematurely.

Related errors


AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13). Data as JSON: /api/errors/1fbc728df94ec93e. Report an issue: GitHub.