Kuberwastaken/claurst · error · anyhow::Error
LSP server stdout not available
Error message
LSP server stdout not available
What it means
Same as the stdin case but for stdout: `child.stdout.take()` returned `None` in `LspClient::start`, so the client cannot build its response-reader pump. Because `start` always pipes stdout, this is effectively an internal invariant violation or an OS-level pipe-creation failure.
Solutions
- Retry startup; check and raise the open-file limit (`ulimit -n`) if fd exhaustion is suspected.
- Audit sandbox/container policies that may block pipe creation.
- Ensure no code path takes stdout from the Child before LspClient::start does.
- Report upstream if reproducible under normal conditions.
Defensive patterns
Strategy: retry
Try / catch
match LspClient::start(config.clone()).await {
Ok(c) => c,
Err(e) if e.to_string().contains("stdout not available") => retry_with_backoff(config, 3).await?,
Err(e) => return Err(e),
} Prevention
- Avoid exhausting file descriptors; raise ulimit -n for hosts spawning many servers.
- Do not intercept the child's stdio handles outside the library.
- Retry transiently; escalate to a bug report on reproducible failures.
When it happens
Trigger: `LspClient::start` with stdout pipes failing to be created by the OS, or the Child handle's stdout already taken before line 220 — not reachable through normal public API usage.
Common situations: fd exhaustion (too many open files) preventing pipe creation; heavily sandboxed environments (containers/seccomp) that restrict pipe allocation; modified library code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- LSP server stdin not available
- LSP server closed stdout
- LSP message missing Content-Length header
- Failed to start LSP server
- LSP client already shut down
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/479f827127519d23.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/core/src/lsp.rs:223
cmd.creation_flags(0x0800_0000u32);
}
let mut child = cmd.spawn().map_err(|e| {
anyhow::anyhow!(
"Failed to start LSP server '{}': {}",
config.command,
e
)
})?;
let stdin = child
.stdin
.take()
.ok_or_else(|| anyhow::anyhow!("LSP server stdin not available"))?;
let stdout = child
.stdout
.take()
.ok_or_else(|| anyhow::anyhow!("LSP server stdout not available"))?;
let pending: PendingMap = Arc::new(DashMap::new());
let diagnostics: Arc<DashMap<String, Vec<LspDiagnostic>>> =
Arc::new(DashMap::new());
let writer = Arc::new(Mutex::new(BufWriter::new(stdin)));
let pending_clone = pending.clone();
let diagnostics_clone = diagnostics.clone();
let server_name = config.name.clone();
// Consume stderr in the background so the OS pipe buffer never fills up
if let Some(stderr) = child.stderr.take() {
let name = server_name.clone();
tokio::spawn(async move {
let mut lines = BufReader::new(stderr).lines();
while let Ok(Some(line)) = lines.next_line().await {
tracing::debug!("[LSP SERVER {}] {}", name, line);
}
View on GitHub (pinned to b0637c97ec)