facebook/flow · error

Failed to create tokio runtime

Error message

Failed to create tokio runtime

What it means

`MakeMain::main` builds the tokio runtime that drives the entire codemod run with `tokio::runtime::Runtime::new().expect("Failed to create tokio runtime")`. Construction fails when the process cannot create the runtime's threads or map their stacks — typically OS resource limits (RLIMIT_NPROC / cgroup pids.max, RLIMIT_STACK, RLIMIT_AS) or memory exhaustion. Since everything runs inside `rt.block_on`, this panic aborts the codemod before any work starts.

Source

Thrown at rust_port/crates/flow_codemods/src/utils/codemod_utils.rs:150

}

impl<Runner: super::codemod_runner::Runnable> MakeMain<Runner> {
    pub fn main(
        options: &Options,
        write: bool,
        repeat: bool,
        log_level: Option<flow_hh_logger::Level>,
        roots: BTreeSet<FileKey>,
    ) {
        initialize_logs(options);
        let log_level = match log_level {
            Some(level) => level,
            None => flow_hh_logger::Level::Off,
        };
        flow_hh_logger::level::set_min_level(log_level);
        let committed_heap = committed_heap_init();
        let genv = make_genv(options, committed_heap);
        let rt = tokio::runtime::Runtime::new().expect("Failed to create tokio runtime");
        rt.block_on(Runner::run(&genv, write, repeat, roots));
    }
}

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Raise thread/process limits: increase the container pids limit or systemd TasksMax, or `ulimit -u <higher>` in the invoking shell, then retry.
  2. Reduce concurrent processes on the machine so thread creation succeeds.
  3. Check memory-related limits (`ulimit -v`, `ulimit -s`) and raise or unset them for the run.
  4. As a code fix, build the runtime with `tokio::runtime::Builder::new_multi_thread().enable_all().worker_threads(1)` and report the io::Error instead of expect.

Example fix

// before
let rt = tokio::runtime::Runtime::new().expect("Failed to create tokio runtime");

// after
let rt = tokio::runtime::Builder::new_multi_thread()
    .enable_all()
    .worker_threads(1)
    .build()
    .unwrap_or_else(|e| { eprintln!("failed to create tokio runtime ({e}); check thread/memory limits"); std::process::exit(1) });
Defensive patterns

Strategy: validation

Validate before calling

// Probe thread creation before building the tokio runtime
fn can_create_threads() -> bool {
    std::thread::spawn(|| ()).join().is_ok()
}
if !can_create_threads() {
    eprintln!("cannot create threads; raise ulimit -u / container pids limit");
    std::process::exit(1);
}

Try / catch

let rt = match tokio::runtime::Builder::new_multi_thread().enable_all().worker_threads(1).build() {
    Ok(rt) => rt,
    Err(e) => {
        eprintln!("failed to create tokio runtime ({e}); check thread/memory limits");
        std::process::exit(1);
    }
};

Prevention

When it happens

Trigger: Running the codemod binary in a container/sandbox with a low pids limit; `ulimit -u` already exhausted by many threads; `ulimit -v` too small for runtime thread stacks; heavily oversubscribed CI machines.

Common situations: Docker/Kubernetes with pids.max limits; systemd user slices with TasksMax; CI jobs launching many binaries in parallel; nix/sandbox environments with strict rlimits.

Related errors


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