{"record":{"id":"5258041a8c9c4947","repo":"facebook/flow","slug":"flow-stack-size-must-be-a-number-got-s","errorCode":null,"errorMessage":"$FLOW_STACK_SIZE must be a number, got {s}","messagePattern":"\\$FLOW_STACK_SIZE must be a number, got (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_utils_concurrency/src/thread_pool.rs","lineNumber":110,"sourceCode":"    {\n        NonZeroUsize::new(num_cpus::get_physical()).unwrap_or_else(logical_parallelism)\n    }\n}\n\n#[cfg(not(target_arch = \"wasm32\"))]\npub struct ThreadPool(Option<rayon::ThreadPool>);\n\n#[cfg(target_arch = \"wasm32\")]\npub struct ThreadPool;\n\nimpl ThreadPool {\n    #[cfg(not(target_arch = \"wasm32\"))]\n    fn stack_size() -> usize {\n        match env::var(\"FLOW_STACK_SIZE\") {\n            Ok(s) => {\n                let res = s\n                    .parse::<usize>()\n                    .unwrap_or_else(|_| panic!(\"$FLOW_STACK_SIZE must be a number, got {s}\"));\n                info!(\n                    \"Using stack size of {} bytes (due to `$FLOW_STACK_SIZE`)\",\n                    number_thousands(res)\n                );\n                res\n            }\n            Err(_) => DEFAULT_STACK_SIZE,\n        }\n    }\n\n    pub fn with_thread_count(count: ThreadCount) -> Self {\n        #[cfg(target_arch = \"wasm32\")]\n        {\n            let _ = count;\n            return Self;\n        }\n        #[cfg(not(target_arch = \"wasm32\"))]\n        {","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_utils_concurrency/src/thread_pool.rs#L92-L128","documentation":"Flow's ThreadPool reads $FLOW_STACK_SIZE to override the default worker stack size (deep recursion in the typechecker needs big stacks). The value must parse as usize — a plain decimal byte count. Any non-numeric value panics the moment a ThreadPool is constructed, which is at server/parser/codemod startup, before any real work starts.","triggerScenarios":"Setting FLOW_STACK_SIZE to a value with units or a non-decimal form — 8MB, 8m, 0x800000, '1 gb', '8_388_608', or an empty string — and then starting any binary that builds a ThreadPool.","commonSituations":"Ops configs copying ulimit-style values with suffixes; CI pipelines exporting the variable globally with a typo; users assuming MiB units; empty assignments like FLOW_STACK_SIZE= in scripts.","solutions":["Set a plain decimal byte count: FLOW_STACK_SIZE=134217728 for 128 MiB.","Unset the variable to fall back to the built-in DEFAULT_STACK_SIZE.","Fix the deployment manifest/script that assigns the suffixed value.","Sanitize the variable in your launcher (strip or unset non-numeric values) so bad configs fail soft."],"exampleFix":"# before\nexport FLOW_STACK_SIZE=8MB   # panic: $FLOW_STACK_SIZE must be a number, got 8MB\n\n# after\nexport FLOW_STACK_SIZE=8388608","handlingStrategy":"validation","validationCode":"# sanitize before launching anything that builds a ThreadPool\nif [ -n \"$FLOW_STACK_SIZE\" ] && ! [[ \"$FLOW_STACK_SIZE\" =~ ^[0-9]+$ ]]; then\n  echo \"FLOW_STACK_SIZE='$FLOW_STACK_SIZE' is not a plain number - unsetting\" >&2\n  unset FLOW_STACK_SIZE\nfi","typeGuard":"# bash type guard for launch scripts\nis_valid_stack_size() { [[ \"$1\" =~ ^[0-9]+$ ]]; }\nis_valid_stack_size \"$FLOW_STACK_SIZE\" || unset FLOW_STACK_SIZE","tryCatchPattern":null,"preventionTips":["Use plain decimal byte counts (134217728 = 128 MiB); never unit suffixes.","Centralize the variable in one manifest and lint it for ^[0-9]+$ in CI.","Document the byte semantics next to every place it is set.","If unsure, unset it and rely on DEFAULT_STACK_SIZE."],"tags":["environment-variables","configuration","thread-pool","startup","stack-size"],"backgroundTag":"invalid-env-var-value","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T06:17:17.905Z"}