{"record":{"id":"c141f1127ee4513b","repo":"slint-ui/slint","slug":"failed-to-join-adapter-thread","errorCode":null,"errorMessage":"Failed to join adapter thread","messagePattern":"Failed to join adapter thread","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/lsp/main.rs","lineNumber":558,"sourceCode":"        let recompile_idle_timeout = if ctx.session.pending_recompile.is_empty() {\n            Duration::MAX\n        } else {\n            RECOMPILE_IDLE_TIMEOUT\n        };\n        tokio::select! {\n            msg = from_lsp_receiver.recv() => {\n                if let Some(msg) = msg {\n                    match handle_lsp_message(\n                        msg,\n                        &connection,\n                        &mut rh,\n                        &mut ctx,\n                        &mut file_watcher\n                    ).await\n                    {\n                        Ok(true) => {\n                            tracing::debug!(\"LSP shutdown requested\");\n                            adapter_thread.join().expect(\"Failed to join adapter thread\");\n                            return Ok(());\n                        }\n                        Ok(false) => {}\n                        Err(e) => tracing::error!(\"Error handling LSP message: {e}\"),\n                    }\n                } else {\n                    adapter_thread.join().expect(\"Failed to join adapter thread\");\n                    return Err(\"LSP connection closed\".into());\n                }\n            }\n            _msg = preview_to_lsp_receiver.recv() => {\n                // Messages from the native preview come in here:\n                #[cfg(feature = \"preview-engine\")]\n                {\n                    if let Some(msg) =\n                        _msg && let Err(err) = handle_preview_to_lsp_message(msg, &mut ctx).await\n                    {\n                        tracing::error!(\"handle_preview_to_lsp_message: {err}\");","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/tools/lsp/main.rs#L540-L576","documentation":"On LSP shutdown, `run_main_loop` joins the dedicated adapter thread that runs the blocking LSP connection handling (`adapter_thread.join().expect(\"Failed to join adapter thread\")`). `join` returns Err only if the joined thread itself panicked, so this expect panics the main loop whenever the adapter thread panicked during handling of LSP messages.","triggerScenarios":"The adapter thread panics at any point while processing LSP messages (e.g. an internal expect/assert in message handling, a lock poisoned, index out of bounds on a document), and then the client sends the `shutdown` request, causing the main loop to join the panicked thread.","commonSituations":"An editor (VS Code, Neovim) sends shutdown after a crash-inducing request; a latent bug in the adapter thread (e.g. handling an unusual document state) panics mid-session and the panic only surfaces at shutdown.","solutions":["Find the root-cause panic: it happened earlier in the adapter thread; scan the log/tracing output for the original panic message and fix that bug.","Update slint-lsp to the latest version — the triggering adapter-thread panic may already be fixed.","Work around operationally by restarting the LSP server/client window after the first panic instead of letting shutdown escalate it.","As a patch, replace the expect with `if adapter_thread.join().is_err() { tracing::error!(\"adapter thread panicked\") }` so shutdown stays graceful."],"exampleFix":"// before\nadapter_thread.join().expect(\"Failed to join adapter thread\");\n\n// after\nif adapter_thread.join().is_err() {\n    tracing::error!(\"adapter thread panicked before shutdown\");\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match adapter_thread.join() {\n    Ok(_) => {},\n    Err(_) => tracing::error!(\"adapter thread panicked; see earlier panic in logs\"),\n}","preventionTips":["Keep full tracing/panic logs — the real bug is the earlier adapter-thread panic.","Send a proper LSP `shutdown` request before killing the server.","Keep slint-lsp updated so known adapter-thread panics are fixed.","Restart the server after any panic instead of continuing the session."],"tags":["lsp","threads","panic","shutdown"],"backgroundTag":"thread-interrupted","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}