{"record":{"id":"4bb3131f40333751","repo":"facebook/flow","slug":"failed-to-spawn-connect-and-make-request-timed-thr","errorCode":null,"errorMessage":"failed to spawn connect_and_make_request_timed thread","messagePattern":"failed to spawn connect_and_make_request_timed thread","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_cli/src/command_utils.rs","lineNumber":3276,"sourceCode":"            let root_owned = root.to_path_buf();\n            let request_clone = request.clone();\n            let initial_retries = connect_flags.retries;\n            std::thread::Builder::new()\n                .name(\"connect_and_make_request_timed\".to_string())\n                .spawn(move || {\n                    let response = connect_and_make_request_inner(\n                        &flowconfig_name_owned,\n                        &connect_flags_clone,\n                        &root_owned,\n                        &request_clone,\n                        initial_retries,\n                    );\n                    match tx.send(response) {\n                        Ok(()) => {}\n                        Err(_) => {}\n                    }\n                })\n                .expect(\"failed to spawn connect_and_make_request_timed thread\");\n            match rx.recv_timeout(std::time::Duration::from_secs(timeout as u64)) {\n                Ok(response) => response,\n                Err(std::sync::mpsc::RecvTimeoutError::Timeout) => flow_common_exit::exit(\n                    flow_common_exit::FlowExitStatus::OutOfTime,\n                    Some(\"Timeout exceeded, exiting\"),\n                ),\n                Err(std::sync::mpsc::RecvTimeoutError::Disconnected) => flow_common_exit::exit(\n                    flow_common_exit::FlowExitStatus::UnknownError,\n                    Some(\"Inner connect thread panicked, exiting\"),\n                ),\n            }\n        }\n    }\n}\n\npub(crate) fn failwith_bad_response(\n    request: &server_prot::request::Command,\n    response: &server_prot::response::Response,","sourceCodeStart":3258,"sourceCodeEnd":3294,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_cli/src/command_utils.rs#L3258-L3294","documentation":"For commands that enforce a timeout, the client spawns a worker thread (named connect_and_make_request_timed) that performs connect_and_make_request_inner and sends the result over an mpsc channel; recv_timeout on the channel enforces the deadline. This expect fires when std::thread::Builder::spawn itself returns Err, i.e. the OS refused to create a thread (pid/thread limit, memory for the thread stack). Nothing about the flow server is involved yet — the panic happens before any request starts.","triggerScenarios":"RLIMIT_NPROC / `ulimit -u` exhausted, a container cgroup pids.max reached, insufficient memory to map the default thread stack, or a sandbox thread cap — at the moment a timeout-flagged flow command runs.","commonSituations":"CI containers started with docker `--pids-limit` (e.g. 100) that already run many processes/threads; systemd TasksMax reached; heavy parallel test matrices saturating thread counts; memory pressure preventing stack allocation.","solutions":["Raise the process/thread budget: increase docker --pids-limit / systemd TasksMax / `ulimit -u`, or reduce the number of concurrent processes on the machine.","Free memory so the thread stack can be allocated; retry once load drops.","Run the command without the timeout option so the timed code path is avoided (if the command allows it).","Maintainer fix: on spawn failure, fall back to calling connect_and_make_request_inner inline (losing the timeout guard) or exit with a clear diagnostic instead of panicking."],"exampleFix":"// before\nlet handle = std::thread::Builder::new()\n    .name(\"connect_and_make_request_timed\".to_string())\n    .spawn(move || { /* inner request, tx.send */ })\n    .expect(\"failed to spawn connect_and_make_request_timed thread\");\n\n// after\nlet spawned = std::thread::Builder::new()\n    .name(\"connect_and_make_request_timed\".to_string())\n    .spawn(move || { /* inner request, tx.send */ });\nlet handle = match spawned {\n    Ok(handle) => handle,\n    Err(e) => {\n        eprintln!(\"could not start timeout worker ({}); running without timeout\", e);\n        return connect_and_make_request_inner(/* ... */);\n    }\n};","handlingStrategy":"fallback","validationCode":"let can_spawn_thread = std::thread::available_parallelism().is_ok(); // rough capacity signal only\nlet pid_budget_ok = std::fs::read_to_string(\"/proc/self/status\")\n    .map(|s| s.lines().any(|l| l.starts_with(\"Threads:\") && l.split_whitespace().nth(1).map(|n| n.parse::<usize>().map(|n| n < 100).unwrap_or(true)).unwrap_or(true)))\n    .unwrap_or(true);","typeGuard":null,"tryCatchPattern":"let spawned = std::thread::Builder::new()\n    .name(\"connect_and_make_request_timed\".to_string())\n    .spawn(move || { /* ... */ });\nmatch spawned {\n    Ok(handle) => { /* wait on rx.recv_timeout as before */ }\n    Err(e) => {\n        eprintln!(\"warning: no threads available ({}); running without timeout\", e);\n        connect_and_make_request_inner(/* ... */)\n    }\n}","preventionTips":["Set docker --pids-limit / systemd TasksMax / ulimit -u generously for build+lint containers.","Monitor thread/process counts before launching flow in saturated environments.","Avoid running flow from processes that already exhausted the thread budget."],"tags":["thread","spawn","resource-limits","timeout","panic","mpsc"],"backgroundTag":"thread-spawn-failure","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}