{"record":{"id":"38231dae41bbe7ed","repo":"facebook/flow","slug":"failed-to-spawn-flow-cli-main-thread","errorCode":null,"errorMessage":"failed to spawn flow_cli_main thread","messagePattern":"failed to spawn flow_cli_main thread","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_cli/src/main.rs","lineNumber":20,"sourceCode":" * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#[allow(non_upper_case_globals)]\n#[unsafe(no_mangle)]\n#[used]\nstatic malloc_conf: &str = \"metadata_thp:always\\0\";\n\nfn main() {\n    #[cfg(windows)]\n    {\n        let handle = std::thread::Builder::new()\n            .name(\"flow_cli_main\".to_string())\n            .stack_size(64 * 1024 * 1024)\n            .spawn(main_)\n            .expect(\"failed to spawn flow_cli_main thread\");\n        if let Err(payload) = handle.join() {\n            std::panic::resume_unwind(payload);\n        }\n    }\n\n    #[cfg(not(windows))]\n    main_();\n}\n\nfn main_() {\n    #[cfg(fbcode_build)]\n    {\n        flow_cli_support::register_extra_commands(|| {\n            vec![\n                flow_facebook_fox_cli::fox_command::command(),\n                flow_facebook_rage::rage_command::command(),\n            ]\n        });","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_cli/src/main.rs#L2-L38","documentation":"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.","triggerScenarios":"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.","commonSituations":"Windows CI containers/runners with tight memory limits; developer machines with small pagefiles running builds + editors + flow simultaneously; older 32-bit toolchains.","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."],"exampleFix":"// before\nlet handle = std::thread::Builder::new()\n    .name(\"flow_cli_main\".to_string())\n    .stack_size(64 * 1024 * 1024)\n    .spawn(main_)\n    .expect(\"failed to spawn flow_cli_main thread\");\n\n// after\nlet spawned = std::thread::Builder::new()\n    .name(\"flow_cli_main\".to_string())\n    .stack_size(64 * 1024 * 1024)\n    .spawn(main_);\nlet handle = match spawned {\n    Ok(handle) => handle,\n    Err(e) => {\n        eprintln!(\"could not start main thread with 64MiB stack ({}); trying current thread\", e);\n        main_();\n        return;\n    }\n};","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let spawned = std::thread::Builder::new()\n    .name(\"flow_cli_main\".to_string())\n    .stack_size(64 * 1024 * 1024)\n    .spawn(main_);\nmatch spawned {\n    Ok(handle) => { if let Err(payload) = handle.join() { std::panic::resume_unwind(payload); } }\n    Err(e) => {\n        eprintln!(\"warning: cannot reserve 64MiB stack ({}); running on current thread\", e);\n        main_();\n    }\n}","preventionTips":["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."],"tags":["windows","thread","stack-size","memory","spawn","panic"],"backgroundTag":"thread-spawn-failure","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}