facebook/flow · error

failed to write codemod output

Error message

failed to write codemod output

What it means

After a codemod mutates a file's AST, `print_ast_file_real` re-prints the transformed source and writes it back over the original file via `std::fs::write(...).expect("failed to write codemod output")`. The panic fires when that write fails: no write permission on the file, read-only filesystem or container mount, disk full or quota exceeded, or the path vanished/became invalid between parse and write.

Source

Thrown at rust_port/crates/flow_codemods/src/utils/codemod_printer.rs:64

                strip_root.as_ref().map(|p| p.to_str().unwrap_or("")),
                file,
            );
            println!(">>> {} (#changes: {})", display_path, diff.len());
            println!("{}", source);
        }
        Some([]) | None => {}
    }
}

pub async fn print_ast_file_real(file: FileKey) -> Option<FileKey> {
    let file_path = file.to_absolute();
    let file_input = FileInput::FileName(file_path.clone());
    let diff = diff_heaps_get_diff(&file);
    match diff.as_deref() {
        Some([_, ..]) => {
            let diff = diff.as_ref().unwrap();
            let source = replacement_printer::print_unsafe(diff, &file_input);
            std::fs::write(&file_path, source).expect("failed to write codemod output");
            Some(file)
        }
        Some([]) | None => None,
    }
}

const MAX_FILES_OPEN: usize = 1024;

pub async fn print_asts(
    strip_root: &Option<PathBuf>,
    write: bool,
    files: Vec<FileKey>,
) -> Option<Vec<FileKey>> {
    fn print_dry(strip_root: &Option<PathBuf>, mut files: Vec<FileKey>) -> Option<Vec<FileKey>> {
        files.sort();
        for file in &files {
            print_ast_file_dry(strip_root, file);
        }

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Check writability of the failing file: `test -w path`; fix permissions (chmod/chown) or remount the volume read-write.
  2. Check capacity: `df -h .` and `df -i .` for space/inode exhaustion, free space or raise quota, then re-run.
  3. Re-run the codemod from a stable, unmodified checkout so files are not deleted mid-run.
  4. If one specific file keeps failing, inspect it for symlink oddities or immutable attributes (`lsattr path`).

Example fix

// before
std::fs::write(&file_path, source).expect("failed to write codemod output");

// after
if let Err(e) = std::fs::write(&file_path, source) {
    eprintln!("skipping {}: cannot write codemod output ({e})", file_path.display());
    return None;
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure each codemod target is writable before running in write mode
use std::fs::OpenOptions;
fn target_is_writable(p: &std::path::Path) -> bool {
    if !p.is_file() { return false; }
    OpenOptions::new().write(true).open(p).is_ok()
}
let all_writable = files.iter().all(|f| target_is_writable(&f.to_absolute()));

Try / catch

if let Err(e) = std::fs::write(&file_path, source) {
    eprintln!("skipping {}: cannot write codemod output ({e})", file_path.display());
    continue;
}

Prevention

When it happens

Trigger: Running a codemod in write mode (`write=true`) on a checkout without write permission or owned by another uid; ENOSPC (disk full, inode exhaustion, quota); file deleted or its symlink target removed while the codemod was running; immutable-bit or ACL denying writes.

Common situations: CI sandboxes with read-only source mounts; Docker volume mounts with mismatched uid/gid; codemods run on a full disk; repos on NFS with stale handles; another process deleting files mid-run.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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