From c4f787ac5079715dd17aa80eefbba0fc2fdd77af Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Sun, 16 Aug 2026 06:57:02 +0200 Subject: [PATCH 1/2] Don't crash on unrecognized cursor contexts Code.Fragment.cursor_context/1 gains new context types with Elixir releases (:capture_arg in 1.17, :block_keyword_or_binary_operator in 1.18) and do_expand/5 raised CaseClauseError on anything it did not know, taking down the LSP completion request and the debug adapter's completions request. Fall back to no suggestions instead. Co-Authored-By: Claude Opus 5 (1M context) --- apps/elixir_ls_utils/lib/completion_engine.ex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/elixir_ls_utils/lib/completion_engine.ex b/apps/elixir_ls_utils/lib/completion_engine.ex index 14c8fafcb..c6744ffeb 100644 --- a/apps/elixir_ls_utils/lib/completion_engine.ex +++ b/apps/elixir_ls_utils/lib/completion_engine.ex @@ -358,6 +358,11 @@ defmodule ElixirLS.Utils.CompletionEngine do :none -> no() + + # cursor_context/1 gains new context types with Elixir releases; an + # unknown one degrades to no suggestions instead of crashing the request + _other -> + no() end end From 203202d0087253cf6c2fe10ca70d8cfd23d11e40 Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Sun, 16 Aug 2026 07:07:43 +0200 Subject: [PATCH 2/2] Drop redundant is_struct/1 check in parser rescue Values bound by rescue are always exception structs, so the guard made the if's else branch unreachable and Elixir 1.20's type checker flagged it, failing the warnings-as-errors CI step. Co-Authored-By: Claude Opus 5 (1M context) --- apps/language_server/lib/language_server/parser.ex | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/language_server/lib/language_server/parser.ex b/apps/language_server/lib/language_server/parser.ex index f741a31a8..ad2b74499 100644 --- a/apps/language_server/lib/language_server/parser.ex +++ b/apps/language_server/lib/language_server/parser.ex @@ -569,12 +569,11 @@ defmodule ElixirLS.LanguageServer.Parser do {:error, diagnostic} e -> - if is_struct(e) and - e.__struct__ in [ - Phoenix.LiveView.Tokenizer.ParseError, - Phoenix.LiveView.HTMLTokenizer.ParseError, - Phoenix.LiveView.TagEngine.Tokenizer.ParseError - ] do + if e.__struct__ in [ + Phoenix.LiveView.Tokenizer.ParseError, + Phoenix.LiveView.HTMLTokenizer.ParseError, + Phoenix.LiveView.TagEngine.Tokenizer.ParseError + ] do diagnostic = Diagnostics.from_error(:error, e, __STACKTRACE__, file, :no_stacktrace)