facebook/flow · critical
failed to spawn LSP log flusher
Error message
failed to spawn LSP log flusher
What it means
The LSP server spawns a background thread that periodically flushes Flow event logs; .expect("failed to spawn LSP log flusher") panics if std::thread::Builder::spawn fails. spawn only fails when the OS cannot create a thread — resource limits (RLIMIT_NPROC, cgroup pids.max) or memory exhaustion. Without this thread, event logs would never be flushed, so the server aborts at startup.
Source
Thrown at rust_port/crates/flow_lsp_server/src/flow_lsp.rs:719
pub fn log_flusher_run() {
std::thread::Builder::new()
.name("flow_lsp_log_flusher".to_string())
.spawn(|| {
loop {
std::thread::sleep(Duration::from_secs(5));
let event_logger_result = flow_tokio_runtime::block_on(async {
let event_logger_flush = flow_event_logger_lwt::flush();
let interaction_flush = crate::lsp_interaction::flush();
let (event_logger_result, ()) =
tokio::join!(event_logger_flush, interaction_flush);
event_logger_result
});
if let Err(err) = event_logger_result {
eprintln!("Failed to flush Flow event logs: {}", err);
}
}
})
.expect("failed to spawn LSP log flusher");
}
use flow_lsp::lsp_fmt;
use crate::jsonrpc::get_next_request_id;
use crate::lsp_interaction;
fn sys_utils_realpath(path: &str) -> Option<String> {
flow_common::files::cached_canonicalize(std::path::Path::new(path))
.ok()
.map(|p| p.to_string_lossy().to_string())
}
fn json_truncate(
json: &serde_json::Value,
max_string_length: usize,
max_child_count: usize,
) -> serde_json::Value {View on GitHub (pinned to 5c86586199)
Solutions
- Raise the process/thread limit: ulimit -u higher, or --pids-limit / cgroup pids.max in containers.
- Reduce the number of concurrent LSP/server processes running simultaneously.
- Increase available memory or the stack allocation environment if spawn fails due to ENOMEM.
- Verify with `ulimit -u` and `cat /proc/sys/kernel/threads-max`, then restart the editor/LSP client.
Example fix
// before (systemd user service / container) TasksMax=128 // after TasksMax=4096 # or: docker run --pids-limit=4096
Defensive patterns
Strategy: fallback
Validate before calling
fn can_spawn_thread() -> bool {
std::thread::Builder::new().spawn(|| {}).map(|h| { let _ = h.join(); true }).unwrap_or(false)
} Try / catch
match std::panic::catch_unwind(start_flow_lsp) {
Ok(_) => {},
Err(_) => eprintln!("LSP failed to start: raise ulimit -u / pids.max"),
} Prevention
- Raise TasksMax/pids-limit for services and containers that host the LSP server.
- Avoid running dozens of LSP sessions concurrently on limited machines.
- Check ulimit -u before launching editors in constrained environments.
- Provision adequate memory for large-monorepo language server workloads.
When it happens
Trigger: Starting the Flow LSP server (flow_lsp.rs startup path) in a process that has exhausted its thread/process allowance or cannot allocate the thread stack.
Common situations: Editor-launched LSP servers inside containers with strict pids.max; many concurrent LSP sessions in CI hitting RLIMIT_NPROC; low ulimit -u on macOS/Linux dev machines; memory pressure on large monorepo workstations.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- failed to spawn init thread
- failed to spawn connection thread
- failed to spawn recheck_cancel_monitor thread
- failed to spawn wait_for_anything thread
- To be able to build a thread pool
AI-assisted analysis of facebook/flow@5c86586199 (2026-09-08).
Data as JSON: /api/errors/dc90f690f8697acc.
Report an issue: GitHub.