facebook/flow · error

failed to read stdin

Error message

failed to read stdin

What it means

When the filename list is fed via stdin (--input-file -), get_filenames_from_input reads it line by line: each item of .lines() is a Result that errors when the bytes are not valid UTF-8 or on a hard I/O failure. The .expect() inside the map panics partway through collect, so one bad byte in the streamed list kills the whole command.

Source

Thrown at rust_port/crates/flow_cli/src/command_utils.rs:137

    let cwd = std::env::current_dir()
        .expect("failed to get current directory")
        .to_string_lossy()
        .to_string();
    let handle_imaginary = |filename: &str| -> String {
        if allow_imaginary {
            flow_common::files::imaginary_realpath(filename)
        } else {
            let msg = format!("File not found: {:?}", filename);
            flow_common_exit::exit(FlowExitStatus::NoInput, Some(&msg));
        }
    };
    let input_file_filenames = match input_file {
        Some("-") => {
            let stdin = std::io::stdin();
            let lines: Vec<String> = stdin
                .lock()
                .lines()
                .map(|l| l.expect("failed to read stdin"))
                .collect();
            flow_common::files::canonicalize_filenames(&cwd, &handle_imaginary, &lines)
        }
        Some(input_file) => {
            let content = std::fs::read_to_string(input_file).expect("failed to read input file");
            let lines: Vec<String> = content.lines().map(|l| l.to_string()).collect();
            let file_dir = Path::new(input_file)
                .parent()
                .map(|p| p.to_string_lossy().to_string())
                .unwrap_or_else(|| cwd.clone());
            flow_common::files::canonicalize_filenames(&file_dir, &handle_imaginary, &lines)
        }
        None => vec![],
    };
    let cli_filenames = match filenames {
        Some(filenames) => {
            let names: Vec<String> = filenames.to_vec();
            flow_common::files::canonicalize_filenames(&cwd, &handle_imaginary, &names)

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Sanitize the list to UTF-8 before piping: `iconv -f UTF-8 -t UTF-8 -c list.txt | flow ... --input-file -`
  2. Locate and rename (or drop) the offending non-UTF-8 filenames from the list
  3. Generate lists with byte-safe tooling and re-encode to UTF-8 (e.g. `find ... | sed` verified with `iconv -l` round-trip)

Example fix

# before
flow check-contents --input-file - < files.txt

# after (strip invalid UTF-8 bytes first)
iconv -f UTF-8 -t UTF-8 -c files.txt | flow check-contents --input-file -
Defensive patterns

Strategy: validation

Validate before calling

# Validate the list is clean UTF-8 BEFORE feeding it to the CLI:
iconv -f UTF-8 -t UTF-8 -c files.txt >/dev/null 2>&1 || \
  echo "list contains invalid UTF-8" 

// Rust: build the list from checked strings only
let raw = std::fs::read("files.txt")?;
let text = String::from_utf8(raw)
    .map_err(|_| "files.txt is not valid UTF-8")?;

Try / catch

// In-process caller guarding against the panic:
let files = std::panic::catch_unwind(||
    get_filenames_from_input(true, Some("-"), None))
    .unwrap_or_default(); // fall back to an empty list + user error

Prevention

When it happens

Trigger: Piping a filename dump containing latin-1/latin-9/cp1252 bytes (old archives, Windows exports) via `flow ... --input-file - < list.txt`; concatenating a binary file into the list; stdin backed by a failing fd or closed abnormally.

Common situations: Generated file lists with non-UTF-8 filenames from older filesystems; CI artifacts saved with wrong encoding; `find` output post-processed by tools that mangle bytes.

Related errors


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/ceb951198d0160b1. Report an issue: GitHub.