facebook/flow · error
ensure_parsed_or_trigger_recheck failed
Error message
ensure_parsed_or_trigger_recheck failed
What it means
In the codemod runner's first merge pass, `flow_services_inference::type_service::ensure_parsed_or_trigger_recheck` parses the merge set and verifies nothing changed on disk since the run began. It returns `Err(RecheckError::Canceled(files))` when files were modified concurrently ("unexpected file changes"), and this expect converts that cancellation into a panic.
Source
Thrown at rust_port/crates/flow_codemods/src/utils/codemod_runner.rs:728
{
let _should_print = _options.profile;
let reader = _transaction.clone();
let get_dependent_files = |_: &flow_common_utils::graph::Graph<FileKey>,
_: &flow_common_utils::graph::Graph<FileKey>,
_: &BTreeSet<FileKey>|
-> std::pin::Pin<
Box<dyn std::future::Future<Output = BTreeSet<FileKey>>>,
> { Box::pin(async { BTreeSet::new() }) };
let (_dependency_info, _components, files_to_merge, _) =
merge_targets(_env, _options, &(), get_dependent_files, &_roots).await;
if let Some(pool) = _workers {
flow_services_inference::type_service::ensure_parsed_or_trigger_recheck(
pool,
&reader,
&Arc::new(_options.clone()),
files_to_merge.clone().into_iter().collect(),
)
.expect("ensure_parsed_or_trigger_recheck failed");
}
let mutator = ();
flow_hh_logger::info!("Merging {} files", files_to_merge.len());
if let Some(pool) = _workers {
let _merge_results = flow_services_inference::merge_service::merge_runner(
pool,
&reader,
_options,
false, // for_find_all_refs
_dependency_info.sig_dependency_graph(),
_components,
&files_to_merge,
move |_transaction: &flow_heap::parsing_heaps::Transaction,
_opts: &Options,
_for_find_all_refs: bool,
_component: vec1::Vec1<FileKey>| {
Ok(merge_job(
&mutator,View on GitHub (pinned to f88ac94bcf)
Solutions
- Re-run the codemod — a one-off concurrent edit during the run is the usual cause.
- Quiesce other writers first: `flow stop`, close or pause the editor's autosave, finish git operations before starting.
- Never run two codemods (or a codemod plus a flow server) on the same root at once.
- If it persists, find the process rewriting files (inotify/audit tools) and pause it for the duration.
Example fix
// before
flow_services_inference::type_service::ensure_parsed_or_trigger_recheck(
pool, &reader, &Arc::new(_options.clone()), files,
).expect("ensure_parsed_or_trigger_recheck failed");
// after
match flow_services_inference::type_service::ensure_parsed_or_trigger_recheck(
pool, &reader, &Arc::new(_options.clone()), files,
) {
Ok(()) => {}
Err(flow_services_inference::type_service::RecheckError::Canceled(files)) => {
eprintln!("{} files changed during the codemod run; re-run on a quiesced repo", files.len());
std::process::exit(2);
}
Err(other) => panic!("ensure_parsed_or_trigger_recheck failed: {other:?}"),
} Defensive patterns
Strategy: retry
Validate before calling
// Cheap staleness probe: mtimes must not change across a short interval before the run
fn files_look_stable(files: &[std::path::PathBuf]) -> bool {
let snap = |fs: &[std::path::PathBuf]| fs.iter()
.map(|p| p.metadata().ok().and_then(|m| m.modified().ok()))
.collect::<Vec<_>>();
let a = snap(files);
std::thread::sleep(std::time::Duration::from_millis(500));
a == snap(files)
} Try / catch
match ensure_parsed_or_trigger_recheck(pool, &reader, &options, files) {
Ok(()) => {}
Err(RecheckError::Canceled(files)) => {
// files changed mid-run: safe to re-run the codemod from scratch once the repo is quiet
eprintln!("{} files changed during the run; retrying", files.len());
}
Err(other) => panic!("{other:?}"),
} Prevention
- Quiesce the repository during codemods: stop the flow server, disable autosave/format-on-save, finish git operations.
- Run only one codemod per repository root at a time (use flock if scripts may race).
- Commit or branch before running so interrupted runs can be re-run safely.
When it happens
Trigger: An editor autosave, format-on-save, git checkout/pull/rebase, another flow process, or a second codemod rewrites one of the files between the codemod's initial parse and this merge step; watchman-style daemons touching the repo during a long run.
Common situations: Running codemods with the IDE open and autosave enabled; concurrent `flow server`/daemon on the same root; scripts that `git pull` while codemods run; two codemods launched in parallel.
Related errors
- 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/b8049bb0e32b4c61.
Report an issue: GitHub.