facebook/flow · error
workers required for init
Error message
workers required for init
What it means
During codemod initialization the runner does `workers.as_ref().expect("workers required for init")`. `Genv.workers` is built by `make_genv`, which creates a thread pool only when `options.max_workers > 0` and sets `None` when `max_workers == 0`. Typed codemod runners need that pool for `init_from_scratch`, so a zero-worker configuration panics here.
Source
Thrown at rust_port/crates/flow_codemods/src/utils/codemod_runner.rs:1194
}
#[allow(unreachable_code)]
async fn init_run(
_genv: &Genv,
_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);
extract_flowlibs_or_exit(options);
let heap_transaction = ActiveTransaction::new(_genv.committed_heap.clone());
let transaction = heap_transaction.handle();
let options_arc = Arc::new(options.clone());
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,
);
let file_options = &options.file_options;
let all = options.all;
let roots = get_target_filename_set(file_options, all, _roots);
let roots = TRC::expand_roots(&env, roots);
let env_files: BTreeSet<FileKey> = env.files.iter().cloned().collect();
let roots: BTreeSet<FileKey> = roots.intersection(&env_files).cloned().collect();
log_input_files(&roots);
let results =
TRC::merge_and_check(&env, workers, options, &profiling, roots, 0, &transaction)
.await?;View on GitHub (pinned to f88ac94bcf)
Solutions
- Run the codemod without `--max-workers 0`, or pass an explicit `--max-workers N` with N >= 1.
- Trace where max_workers becomes 0 (CLI flag parsing, .flowconfig, environment) and fix the value.
- If constructing the environment in code, use `make_genv` with max_workers >= 1 so a pool is created.
Example fix
// before
let pool = workers.as_ref().expect("workers required for init");
// after
let Some(pool) = workers.as_ref() else {
eprintln!("codemod requires at least one worker (max_workers is 0); pass --max-workers >= 1");
std::process::exit(2);
}; Defensive patterns
Strategy: validation
Validate before calling
// Before launching the codemod, reject a zero worker configuration
if options.max_workers < 1 {
eprintln!("codemod requires max_workers >= 1 (got {})", options.max_workers);
std::process::exit(2);
} Try / catch
let Some(pool) = workers.as_ref() else {
eprintln!("max_workers is 0; pass --max-workers >= 1");
std::process::exit(2);
}; Prevention
- Never pass --max-workers 0 to codemod binaries; omit the flag to use the default pool.
- Validate max_workers at configuration load time, not deep in the runner.
- When embedding the runner, build Genv via make_genv with max_workers >= 1.
When it happens
Trigger: Launching the codemod binary with `--max-workers 0` (or a config/env override that zeroes max_workers); building a Genv manually with max_workers=0 and then running a runner that requires a pool.
Common situations: Users passing `--max-workers 0` intending single-threaded execution; flag values copied from other tools where 0 means auto; tests embedding the runner with a minimal Genv.
Related errors
- workers required for recheck
- $FLOW_STACK_SIZE must be a number, got {s}
- max_workers should be positive
- ${message}
- import/export cannot be inserted into a ${insertionParent.pa
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/4fd96d1e82c4685d.
Report an issue: GitHub.