facebook/flow · error

Replacement_printer: Input file, "{}", couldn't be read.

Error message

Replacement_printer: Input file, "{}", couldn't be read.

What it means

The replacement printer produces codemod output by reading the original file and applying an AST-diff patch to its text. with_content_of_file_input() calls content_of_file_input(); if that read returns Err — missing file, permission denied, path is a directory — the function panics with the filename, because computing replacements without the source content is impossible.

Source

Thrown at rust_port/crates/flow_parser_utils_output/src/replacement_printer.rs:42

    list_utils::to_string(
        "",
        |(s, e, p): &(usize, usize, String)| {
            format!("Start: <{}> End: <{}> Patch: <{}>\n", s, e, p)
        },
        p,
    )
}

fn with_content_of_file_input<T>(file: &FileInput, f: impl FnOnce(&str) -> T) -> T {
    match file.content_of_file_input() {
        Ok(contents) => f(&contents),
        Err(_) => {
            let file_name = file.filename_of_file_input();
            let error_msg = format!(
                "Replacement_printer: Input file, \"{}\", couldn't be read.",
                file_name
            );
            panic!("{}", error_msg)
        }
    }
}

pub fn mk_loc_patch_ast_differ(opts: &Opts, diff: &NodeChanges) -> LocPatch {
    ast_diff_printer::edits_of_changes(opts, diff)
}

pub fn mk_patch_ast_differ(opts: &Opts, diff: &NodeChanges, content: &str) -> Patch {
    let offset_table = OffsetTable::make(content);
    let offset = |pos: Position| -> usize { offset_table.offset(pos).unwrap() as usize };
    mk_loc_patch_ast_differ(opts, diff)
        .into_iter()
        .map(|(loc, text)| (offset(loc.start), offset(loc.end), text))
        .collect()
}

pub fn mk_patch_ast_differ_unsafe(opts: &Opts, diff: &NodeChanges, file: &FileInput) -> Patch {

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Verify the filename from the panic message: test -r <file>; fix the input path if it is wrong.
  2. Re-run on a clean checkout with concurrent tooling stopped (stash, close the editor, stop watchers).
  3. When batching codemods, run them sequentially and re-stat each input right before the printing step, skipping deleted files.
  4. Patch with_content_of_file_input to return an error or skip-with-warning instead of panicking, if you control the fork.

Example fix

// before
with_content_of_file_input(&file, |content| print_patches(content));

// after: guard, then print
if file.content_of_file_input().is_err() {
    eprintln!("skipping unreadable input: {}", file.filename_of_file_input());
    return Ok(());
}
with_content_of_file_input(&file, |content| print_patches(content));
Defensive patterns

Strategy: validation

Validate before calling

use std::io::Read;

fn file_readable(path: &str) -> bool {
    std::fs::File::open(path)
        .and_then(|mut f| { let mut b = [0u8; 1]; f.read(&mut b).map(|_| ()) })
        .is_ok()
}

// skip inputs that would panic the replacement printer
if !file_readable(input_path) { continue; }

Try / catch

let out = std::panic::catch_unwind(|| with_content_of_file_input(&file, print_fn));
if out.is_err() {
    eprintln!("skipping unreadable input: {}", file.filename_of_file_input());
    continue; // codemod continues with remaining files
}

Prevention

When it happens

Trigger: Running a codemod/transform that routes through the replacement printer when the FileInput path no longer exists or is unreadable at print time: the file was deleted after discovery (another codemod in the same batch, a concurrent git operation), the path is wrong, or permissions deny the read.

Common situations: Codemods run while editors/watchers rewrite files; batched codemods where an earlier one deletes inputs of a later one; sandboxes without read access; --input arguments that are directories or have typos; files swapped by a rebase between diffing and printing.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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