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.
Source
Thrown at rust_port/crates/flow_codemods/src/utils/codemod_runner.rs:1255
_roots.iter().cloned().collect();
updates.add(Some(focused_set), None, None);
let find_ref_request = flow_services_references::find_refs_types::empty_request();
let files_to_force = flow_common_utils::checked_set::CheckedSet::empty();
let mut will_be_checked_files = flow_common_utils::checked_set::CheckedSet::empty();
let recheck_result = flow_services_inference::type_service::recheck(
pool,
&_genv.committed_heap,
&options_arc,
&updates,
&find_ref_request,
files_to_force,
false,
None, // changed_mergebase
false, // missed_changes
&mut will_be_checked_files,
Arc::new(env),
);
let (_, _, _, prepared) = recheck_result.expect("recheck failed");
let env = prepared.commit();
let transaction = ActiveTransaction::new(_genv.committed_heap.clone());
log_input_files(&_roots);
let results = TRC::merge_and_check(
&env,
workers,
options,
&profiling,
_roots,
_iteration,
&transaction.handle(),
)
.await?;
let env = EnvTransaction::new(env).into_env();
Ok(((), (env, results)))
}
#[allow(unreachable_code)]View on GitHub (pinned to f88ac94bcf)
Solutions
- Re-run the codemod on a quiesced repository — a transient concurrent edit is the normal cause.
- Stop concurrent writers: `flow stop`, disable autosave/format-on-save, finish git operations first.
- Serialize codemods per repository root.
- 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
- Stop concurrent writers (flow server, editors with autosave, git) for the whole codemod run.
- Serialize codemods per root.
- Commit before running so a canceled recheck loses nothing.
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
- ensure_parsed_or_trigger_recheck failed
- workers required for recheck
- ${message}
- import/export cannot be inserted into a ${insertionParent.pa
- Tried to remove ${node.type} from parent of type ${node.pare
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/6c3922ce831e92a8.
Report an issue: GitHub.