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
- Free memory or enlarge the pagefile so at least 64 MiB can be committed, then retry.
- Use a 64-bit build of flow (avoids address-space limits).
- Raise job-object/container commit limits on CI agents.
- 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
- Keep Windows commit headroom (RAM + pagefile) above 64 MiB plus working-set needs; enlarge the pagefile rather than disabling it.
- Prefer 64-bit flow builds over 32-bit.
- Raise job-object/container commit limits on CI agents; avoid launching flow alongside memory-saturating builds.
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
- failed to spawn connect_and_make_request_timed thread
- failed to spawn glean_runner_visit_timeout thread
- failed to spawn flow_server_main thread
- To be able to build a thread pool
- Unknown exception reading from the server: {}
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/38231dae41bbe7ed.
Report an issue: GitHub.