facebook/flow · error

recheck failed

Error message

recheck failed

What it means

The codemod's incremental recheck calls `type_service::recheck`, which returns `Err(RecheckError)` with variants `TooSlow` and `Canceled(files)`. Here it is invoked with `changed_mergebase: None`, and per the code comment TooSlim/TooSlow requires `changed_mergebase=Some(true)`, so a failure at this expect means `Canceled`: files changed unexpectedly on disk while the recheck was running.

Solutions

  1. Re-run the codemod on a quiesced repository — a transient concurrent edit is the normal cause.
  2. Stop concurrent writers: `flow stop`, disable autosave/format-on-save, finish git operations first.
  3. Serialize codemods per repository root.
  4. For very large codemods, split into batches to shrink the window in which edits cancel the recheck.

Example fix

// before
let (_, _, _, prepared) = recheck_result.expect("recheck failed");

// after
let (_, _, _, prepared) = match recheck_result {
    Ok(r) => r,
    Err(flow_services_inference::type_service::RecheckError::Canceled(files)) => {
        eprintln!("{} files changed during recheck; re-run the codemod on a quiet repo", files.len());
        std::process::exit(2);
    }
    Err(other) => panic!("recheck failed: {other:?}"),
};
Defensive patterns

Strategy: retry

Validate before calling

// Reduce the race window: confirm roots are quiet immediately before recheck
fn roots_quiet(roots: &BTreeSet<FileKey>) -> bool {
    let m = |f: &FileKey| std::fs::metadata(f.to_absolute()).ok().and_then(|x| x.modified().ok());
    let a: Vec<_> = roots.iter().map(m).collect();
    std::thread::sleep(std::time::Duration::from_millis(300));
    roots.iter().map(m).eq(a.into_iter())
}

Try / catch

let (_, _, _, prepared) = match recheck_result {
    Ok(r) => r,
    Err(RecheckError::Canceled(files)) => {
        eprintln!("{} files changed during recheck; re-run the codemod", files.len());
        std::process::exit(2);
    }
    Err(other) => panic!("recheck failed: {other:?}"),
};

Prevention

When it happens

Trigger: Autosave, formatter, git checkout, or another flow process rewrites files while the codemod is in its recheck/merge-check phase; long runs make the race window larger.

Common situations: IDE open with autosave during a long codemod; concurrent daemons (watchman, flow server, second codemod) on the same root; scripts mutating the repo in parallel with the codemod.

Related errors


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

Appendix: source

Thrown at rust_port/crates/flow_codemods/src/utils/codemod_runner.rs:1258

    type Accumulator = TRC::Accumulator;

    fn reporter() -> codemod_report::CodemodReport<Self::Accumulator> {
        TRC::reporter()
    }

    #[allow(unreachable_code)]
    async fn init_run(
        _genv: &Genv,
        heap: &Arc<CommittedHeap>,
        _roots: BTreeSet<FileKey>,
    ) -> Result<
        ((), (Self::Env, ResultList<Self::Accumulator>)),
        flow_utils_concurrency::worker_cancel::WorkerCanceled,
    > {
        let options = &*_genv.options;
        let workers = &_genv.workers;
        let should_print_summary = options.profile;
        let profiling = profiling_start("Codemod", should_print_summary);
        let (heap_transaction, transaction, options_arc) =
            with_memory_timer(options, "CodemodInit", || {
                extract_flowlibs_or_exit(options);
                let heap_transaction = ActiveTransaction::new(heap.clone());
                let transaction = heap_transaction.handle();
                let options_arc = Arc::new(options.clone());
                (heap_transaction, transaction, options_arc)
            });
        let pool = workers.as_ref().expect("workers required for init");
        let root = &options.root;
        // let%lwt (_libs_ok, env) = Types_js.init ~profiling ~workers options in
        let (env, _libs_ok) = flow_services_inference::type_service::init_from_scratch(
            &options_arc,
            pool,
            &transaction,
            root,
            None,
        );

View on GitHub (pinned to 21c11b2ead)