facebook/flow · error

failed to spawn flow_cli_main thread

Error message

failed to spawn flow_cli_main thread

What it means

On Windows, the real entry point runs on a dedicated thread with a 64 MiB stack ('flow_cli_main') because parsing/typechecking recurses deeply and the default 1–2 MiB main-thread stack overflows. This expect fires before any command executes when CreateThread fails — in practice when the OS cannot reserve/commit 64 MiB of stack (commit limit = RAM + pagefile exhausted, job-object memory cap, or 32-bit address-space fragmentation). The join/resume_unwind below handles panics inside main_, not spawn failure.

Source

Thrown at rust_port/crates/flow_cli/src/main.rs:20

 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#[allow(non_upper_case_globals)]
#[unsafe(no_mangle)]
#[used]
static malloc_conf: &str = "metadata_thp:always\0";

fn main() {
    #[cfg(windows)]
    {
        let handle = std::thread::Builder::new()
            .name("flow_cli_main".to_string())
            .stack_size(64 * 1024 * 1024)
            .spawn(main_)
            .expect("failed to spawn flow_cli_main thread");
        if let Err(payload) = handle.join() {
            std::panic::resume_unwind(payload);
        }
    }

    #[cfg(not(windows))]
    main_();
}

fn main_() {
    #[cfg(fbcode_build)]
    {
        flow_cli_support::register_extra_commands(|| {
            vec![
                flow_facebook_fox_cli::fox_command::command(),
                flow_facebook_rage::rage_command::command(),
            ]
        });

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Free memory or enlarge the pagefile so at least 64 MiB can be committed, then retry.
  2. Use a 64-bit build of flow (avoids address-space limits).
  3. Raise job-object/container commit limits on CI agents.
  4. Maintainer fix: on spawn failure, retry with a smaller stack size or run main_() on the current thread with a clear warning about deep-recursion stack overflow risk.

Example fix

// before
let handle = std::thread::Builder::new()
    .name("flow_cli_main".to_string())
    .stack_size(64 * 1024 * 1024)
    .spawn(main_)
    .expect("failed to spawn flow_cli_main thread");

// after
let spawned = std::thread::Builder::new()
    .name("flow_cli_main".to_string())
    .stack_size(64 * 1024 * 1024)
    .spawn(main_);
let handle = match spawned {
    Ok(handle) => handle,
    Err(e) => {
        eprintln!("could not start main thread with 64MiB stack ({}); trying current thread", e);
        main_();
        return;
    }
};
Defensive patterns

Strategy: fallback

Try / catch

let spawned = std::thread::Builder::new()
    .name("flow_cli_main".to_string())
    .stack_size(64 * 1024 * 1024)
    .spawn(main_);
match spawned {
    Ok(handle) => { if let Err(payload) = handle.join() { std::panic::resume_unwind(payload); } }
    Err(e) => {
        eprintln!("warning: cannot reserve 64MiB stack ({}); running on current thread", e);
        main_();
    }
}

Prevention

When it happens

Trigger: Launching any flow command on Windows under memory pressure: pagefile too small or disabled, CI agent job caps on commit memory, many heavy processes running, or a 32-bit flow binary whose address space cannot host the 64 MiB stack.

Common situations: Windows CI containers/runners with tight memory limits; developer machines with small pagefiles running builds + editors + flow simultaneously; older 32-bit toolchains.

Related errors


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