gleam-lang/gleam · error
joining_lsp_threads
Error message
joining_lsp_threads
What it means
gleam lsp runs over stdio: lsp_server::Connection::stdio() spawns an input thread and an output thread; after LanguageServer::run() completes, io_threads.join().expect("joining_lsp_threads") propagates a panic if either thread panicked. The join error is always a downstream symptom — the real failure is an earlier panic in the message loop (for example an internal compiler invariant hit while processing a didChange request) printed above this one in the editor's LSP log.
Source
Thrown at compiler-cli/src/lsp.rs:48
ignore this message.
If you have run `gleam lsp` yourself in your terminal then exit
this program by pressing ctrl+c.
"
);
}
// Create the transport. Includes the stdio (stdin and stdout) versions but this could
// also be implemented to use sockets or HTTP.
let (connection, io_threads) = lsp_server::Connection::stdio();
// Run the server and wait for the two threads to end, typically by trigger
// LSP Exit event.
LanguageServer::new(&connection, ProjectIO::new())?.run()?;
// Shut down gracefully.
drop(connection);
io_threads.join().expect("joining_lsp_threads");
tracing::info!("language_server_stopped");
Ok(())
}
#[derive(Debug)]
pub struct LspLocker(BuildLock);
impl LspLocker {
pub fn new(paths: &ProjectPaths, target: Target) -> Result<Self> {
let build_lock = BuildLock::new_target(paths, Mode::Lsp, target)?;
Ok(Self(build_lock))
}
}
impl Locker for LspLocker {
fn lock_for_build(&self) -> Result<LockGuard> {
let guard: Guard = self.0.lock(&NullTelemetry)?;View on GitHub (pinned to 7e623aa83d)
Solutions
- Open the editor's LSP log (VS Code: Output panel → Gleam; Neovim: :LspLog) and look for the FIRST panic/stack trace above 'joining_lsp_threads' — that is the actual bug.
- Close the file that triggers it, restart the language server / editor to recover.
- Update (or pin) the gleam version — LSP panics are fixed frequently, and a mismatch between generated code and server can matter.
- Minimize the triggering module and report an issue at github.com/gleam-lang/gleam including the stack trace and `gleam --version`.
Defensive patterns
Strategy: retry
Prevention
- Editors: enable automatic LSP restart (VS Code 'server exited unexpectedly' retry; nvim-lspconfig automatic retrigger) so a crash self-heals.
- Pin a known-good gleam version per project to avoid regressions that panic the server.
- When a crash reproduces on one file, check the LSP log for the FIRST panic above 'joining_lsp_threads' — that backtrace is the actionable one to report.
When it happens
Trigger: The LSP server panicking while handling a specific request (completion, hover, didSave over some edge-case code), stdin/stdout being torn down while a thread is mid-write, or the editor killing the process during shutdown. The join expect then fires as the process unwinds.
Common situations: VS Code / Neovim / Helix showing 'gleam language server crashed' or 'server exited unexpectedly'; restart loops when a particular file is open; frequently correlates with a compiler-version regression.
Related errors
- Unable to start Tokio async runtime
- Unable to start Tokio async runtime
- `panic` expression evaluated.
- could not lock beam_compiler
- Writing warning to stderr
AI-assisted analysis of gleam-lang/gleam@7e623aa83d (2026-08-17).
Data as JSON: /api/errors/b803ca47e2e6a0b9.
Report an issue: GitHub.