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

  1. Run the codemod without `--max-workers 0`, or pass an explicit `--max-workers N` with N >= 1.
  2. Trace where max_workers becomes 0 (CLI flag parsing, .flowconfig, environment) and fix the value.
  3. 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

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


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