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

  1. 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.
  2. Close the file that triggers it, restart the language server / editor to recover.
  3. Update (or pin) the gleam version — LSP panics are fixed frequently, and a mismatch between generated code and server can matter.
  4. 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

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


AI-assisted analysis of gleam-lang/gleam@7e623aa83d (2026-08-17). Data as JSON: /api/errors/b803ca47e2e6a0b9. Report an issue: GitHub.