I have the following snippet, where a binary is incorrectly being passed to get_first/2, which expects a %RIS.Record{}, and an unused argument (this_ris).
On change, both warnings are flagged in my editor (Neovim, expert tested using 0.1.4 and 0.1.5, Elixir 1.20.1). On save, however, only the latter type incompatibility is reported and the former unused variable is not flagged.
Sorry it's not the clearest what is happening in this clip, but first I make a change deleting two spaces, then write it, so that the first warning disappears when both should persist. Repeating the sequence, I make a minor edit adding a space, the warning reappears, then disappears after write.
If it is helpful, you can see in the attached debug logs the mismatching errors (change first, then save after a short amount of time). After didChange there is a warning for variable "this_ris" is unused, but it does not appear after didSave. I have just reinstalled everything to be sure, and cleared expert's caches. A few restarts ago the discrepancy was actually different - the unused variable would always show, but the type error would only show after a change and not after saving. Here are the logs.
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:277 "rpc.send" { jsonrpc = "2.0", method = "textDocument/didChange", params = { contentChanges = { { range = { ["end"] = { character = 40, line = 10 }, start = { character = 40, line = 10 } }, rangeLength = 0, text = " " } }, textDocument = { uri = "file:////lib/extraction/matching/ris.ex", version = 31 } } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "unused require Logger", range = { ["end"] = { character = 0, line = 2 }, start = { character = 2, line = 1 } }, severity = 2, source = "Elixir" }, { message = 'variable "h" is unused', range = { ["end"] = { character = 0, line = 87 }, start = { character = 43, line = 86 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/api/pubmed/metadata.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "unused require Logger", range = { ["end"] = { character = 0, line = 19 }, start = { character = 2, line = 18 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/api/wos/save_to_file.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "article" is unused', range = { ["end"] = { character = 0, line = 61 }, start = { character = 45, line = 60 } }, severity = 2, source = "Elixir" }, { message = 'variable "source" is unused', range = { ["end"] = { character = 0, line = 118 }, start = { character = 40, line = 117 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/cochrane_pipeline.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "module attribute @sec_fetch_user was set but never used", range = { ["end"] = { character = 0, line = 12 }, start = { character = 2, line = 11 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/cochrane_review_request.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "module attribute @cref_url was set but never used", range = { ["end"] = { character = 0, line = 6 }, start = { character = 2, line = 5 } }, severity = 2, source = "Elixir" }, { message = "the following clause will never match:\n\n %{metadata: {:err, _}, ris: _} ->\n\nit is expected to match on type:\n\n dynamic(%{metadata: not {:ok, term()}} or %{metadata: {:ok, term()}, ris: not {:ok, term()}})\n", range = { ["end"] = { character = 0, line = 144 }, start = { character = 12, line = 143 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/hydration.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function py_score/2 is unused", range = { ["end"] = { character = 0, line = 21 }, start = { character = 7, line = 20 } }, severity = 2, source = "Elixir" }, { message = 'incompatible types given to RIS.Record.get_first/2:\n\n RIS.Record.get_first(" ", :TI)\n\ngiven types:\n\n -binary()-, :TI\n\nbut expected one of:\n\n %RIS.Record{}, term()\n', range = { ["end"] = { character = 0, line = 11 }, start = { character = 28, line = 10 } }, severity = 2, source = "Elixir" }, { message = 'variable "this_ris" is unused', range = { ["end"] = { character = 27, line = 9 }, start = { character = 19, line = 9 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/matching/ris.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function analyse_issue_pagination/2 is unused", range = { ["end"] = { character = 0, line = 287 }, start = { character = 7, line = 286 } }, severity = 2, source = "Elixir" }, { message = "function compare_hits/2 is unused", range = { ["end"] = { character = 0, line = 249 }, start = { character = 7, line = 248 } }, severity = 2, source = "Elixir" }, { message = "function pick_best_match/2 is unused", range = { ["end"] = { character = 0, line = 236 }, start = { character = 7, line = 235 } }, severity = 2, source = "Elixir" }, { message = 'the underscored variable "_html" is used after being set. A leading underscore indicates that the value of the variable should be ignored. If this is intended please rename the variable to remove the underscore', range = { ["end"] = { character = 0, line = 39 }, start = { character = 57, line = 38 } }, severity = 2, source = "Elixir" }, { message = 'variable "html_issue_article" is unused', range = { ["end"] = { character = 0, line = 334 }, start = { character = 29, line = 333 } }, severity = 2, source = "Elixir" }, { message = 'variable "html_pagination" is unused', range = { ["end"] = { character = 0, line = 328 }, start = { character = 26, line = 327 } }, severity = 2, source = "Elixir" }, { message = 'variable "issue_pagination" is unused', range = { ["end"] = { character = 0, line = 32 }, start = { character = 28, line = 31 } }, severity = 2, source = "Elixir" }, { message = 'variable "s" is unused', range = { ["end"] = { character = 0, line = 230 }, start = { character = 50, line = 229 } }, severity = 2, source = "Elixir" }, { message = 'variable "unaltered_string" is unused', range = { ["end"] = { character = 0, line = 298 }, start = { character = 13, line = 297 } }, severity = 2, source = "Elixir" }, { message = 'variable "volume" is unused', range = { ["end"] = { character = 0, line = 280 }, start = { character = 22, line = 279 } }, severity = 2, source = "Elixir" }, { message = 'variable "wos_year" is unused', range = { ["end"] = { character = 0, line = 273 }, start = { character = 20, line = 272 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/matching/wos.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function init/1 required by behaviour GenServer is not implemented (in module LLMAnalysis.Flows.FlowManagement.ConcurrencyManager).\n\nWe will inject a default implementation for now:\n\n def init(init_arg) do\n {:ok, init_arg}\n end\n\nYou can copy the implementation above or define your own that converts the arguments given to GenServer.start_link/3 to the server state.\n", range = { ["end"] = { character = 0, line = 1 }, start = { character = 0, line = 0 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/flows/flow_management/concurrency_manager.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "module attribute @models was set but never used", range = { ["end"] = { character = 0, line = 10 }, start = { character = 2, line = 9 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/flows/handlers/simple_anthropic.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "fp" is unused', range = { ["end"] = { character = 0, line = 169 }, start = { character = 62, line = 168 } }, severity = 2, source = "Elixir" }, { message = 'variable "results" is unused', range = { ["end"] = { character = 0, line = 73 }, start = { character = 4, line = 72 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/job_data/structured_result.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "attempt" is unused', range = { ["end"] = { character = 0, line = 5 }, start = { character = 33, line = 4 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/workers/structuring.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "unused require Logger", range = { ["end"] = { character = 0, line = 3 }, start = { character = 2, line = 2 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/workers/unstructured.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "default values for the optional arguments in the private function load_ris_in_dir!/2 are never used", range = { ["end"] = { character = 0, line = 676 }, start = { character = 7, line = 675 } }, severity = 2, source = "Elixir" }, { message = "function load_ris_in_dir/2 is unused", range = { ["end"] = { character = 0, line = 687 }, start = { character = 7, line = 686 } }, severity = 2, source = "Elixir" }, { message = "function start/0 is unused", range = { ["end"] = { character = 0, line = 34 }, start = { character = 7, line = 33 } }, severity = 2, source = "Elixir" }, { message = 'variable "step_3c_labels" is unused', range = { ["end"] = { character = 0, line = 134 }, start = { character = 4, line = 133 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/proj_utils.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "pid" is unused', range = { ["end"] = { character = 0, line = 143 }, start = { character = 12, line = 142 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/requests/llm/anthropic.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function server_info/2 is unused", range = { ["end"] = { character = 0, line = 614 }, start = { character = 7, line = 613 } }, severity = 2, source = "Elixir" }, { message = 'variable "from" is unused', range = { ["end"] = { character = 0, line = 215 }, start = { character = 40, line = 214 } }, severity = 2, source = "Elixir" }, { message = 'variable "reason" is unused', range = { ["end"] = { character = 0, line = 314 }, start = { character = 16, line = 313 } }, severity = 2, source = "Elixir" }, { message = 'variable "s" is unused', range = { ["end"] = { character = 0, line = 389 }, start = { character = 9, line = 388 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/requests/server.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "x" is unused', range = { ["end"] = { character = 0, line = 74 }, start = { character = 6, line = 73 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/statistics/performance/common.ex" } }
[DEBUG][2026-06-18 14:05:44] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function get_arguments/1 is unused", range = { ["end"] = { character = 0, line = 416 }, start = { character = 7, line = 415 } }, severity = 2, source = "Elixir" }, { message = "function inspect_path/1 is unused", range = { ["end"] = { character = 0, line = 431 }, start = { character = 7, line = 430 } }, severity = 2, source = "Elixir" }, { message = "unused require Logger", range = { ["end"] = { character = 0, line = 109 }, start = { character = 2, line = 108 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 111 }, start = { character = 36, line = 110 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 160 }, start = { character = 34, line = 159 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 290 }, start = { character = 19, line = 289 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 333 }, start = { character = 19, line = 332 } }, severity = 2, source = "Elixir" }, { message = 'variable "tag" is unused', range = { ["end"] = { character = 0, line = 131 }, start = { character = 33, line = 130 } }, severity = 2, source = "Elixir" }, { message = 'variable "tag_data" is unused', range = { ["end"] = { character = 0, line = 420 }, start = { character = 20, line = 419 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/xml/handlers/pubmed.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:277 "rpc.send" { jsonrpc = "2.0", method = "textDocument/didSave", params = { textDocument = { uri = "file:////lib/extraction/matching/ris.ex" } } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { id = 13, jsonrpc = "2.0", method = "window/workDoneProgress/create", params = { token = 194 } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:407 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:277 "rpc.send" { id = 13, jsonrpc = "2.0", result = vim.NIL }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 194, value = { kind = "begin", title = "Building cochrane-dataset-tools" } } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 194, value = { kind = "report", message = "Compiling cochrane-dataset-tools" } } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 194, value = { kind = "report", message = "compiling: lib/.../ris.ex" } } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 194, value = { kind = "end" } } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "window/logMessage", params = { message = "Compiled cochrane-dataset-tools in 227 ms", type = 3 } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { id = 14, jsonrpc = "2.0", method = "window/workDoneProgress/create", params = { token = 70 } }
[INFO][2026-06-18 14:06:03] ...lsp/handlers.lua:566 "Compiled cochrane-dataset-tools in 227 ms"
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:407 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:277 "rpc.send" { id = 14, jsonrpc = "2.0", result = vim.NIL }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "unused require Logger", range = { ["end"] = { character = 0, line = 2 }, start = { character = 2, line = 1 } }, severity = 2, source = "Elixir" }, { message = 'variable "h" is unused', range = { ["end"] = { character = 0, line = 87 }, start = { character = 43, line = 86 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/api/pubmed/metadata.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 70, value = { kind = "begin", title = "Finding Completion Candidates" } } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "unused require Logger", range = { ["end"] = { character = 0, line = 19 }, start = { character = 2, line = 18 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/api/wos/save_to_file.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "article" is unused', range = { ["end"] = { character = 0, line = 61 }, start = { character = 45, line = 60 } }, severity = 2, source = "Elixir" }, { message = 'variable "source" is unused', range = { ["end"] = { character = 0, line = 118 }, start = { character = 40, line = 117 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/cochrane_pipeline.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "module attribute @sec_fetch_user was set but never used", range = { ["end"] = { character = 0, line = 12 }, start = { character = 2, line = 11 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/cochrane_review_request.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "module attribute @cref_url was set but never used", range = { ["end"] = { character = 0, line = 6 }, start = { character = 2, line = 5 } }, severity = 2, source = "Elixir" }, { message = "the following clause will never match:\n\n %{metadata: {:err, _}, ris: _} ->\n\nit is expected to match on type:\n\n dynamic(%{metadata: not {:ok, term()}} or %{metadata: {:ok, term()}, ris: not {:ok, term()}})\n", range = { ["end"] = { character = 0, line = 144 }, start = { character = 12, line = 143 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/hydration.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function py_score/2 is unused", range = { ["end"] = { character = 0, line = 21 }, start = { character = 7, line = 20 } }, severity = 2, source = "Elixir" }, { message = 'incompatible types given to RIS.Record.get_first/2:\n\n RIS.Record.get_first(" ", :TI)\n\ngiven types:\n\n -binary()-, :TI\n\nbut expected one of:\n\n %RIS.Record{}, term()\n', range = { ["end"] = { character = 0, line = 11 }, start = { character = 28, line = 10 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/matching/ris.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function analyse_issue_pagination/2 is unused", range = { ["end"] = { character = 0, line = 287 }, start = { character = 7, line = 286 } }, severity = 2, source = "Elixir" }, { message = "function compare_hits/2 is unused", range = { ["end"] = { character = 0, line = 249 }, start = { character = 7, line = 248 } }, severity = 2, source = "Elixir" }, { message = "function pick_best_match/2 is unused", range = { ["end"] = { character = 0, line = 236 }, start = { character = 7, line = 235 } }, severity = 2, source = "Elixir" }, { message = 'the underscored variable "_html" is used after being set. A leading underscore indicates that the value of the variable should be ignored. If this is intended please rename the variable to remove the underscore', range = { ["end"] = { character = 0, line = 39 }, start = { character = 57, line = 38 } }, severity = 2, source = "Elixir" }, { message = 'variable "html_issue_article" is unused', range = { ["end"] = { character = 0, line = 334 }, start = { character = 29, line = 333 } }, severity = 2, source = "Elixir" }, { message = 'variable "html_pagination" is unused', range = { ["end"] = { character = 0, line = 328 }, start = { character = 26, line = 327 } }, severity = 2, source = "Elixir" }, { message = 'variable "issue_pagination" is unused', range = { ["end"] = { character = 0, line = 32 }, start = { character = 28, line = 31 } }, severity = 2, source = "Elixir" }, { message = 'variable "s" is unused', range = { ["end"] = { character = 0, line = 230 }, start = { character = 50, line = 229 } }, severity = 2, source = "Elixir" }, { message = 'variable "unaltered_string" is unused', range = { ["end"] = { character = 0, line = 298 }, start = { character = 13, line = 297 } }, severity = 2, source = "Elixir" }, { message = 'variable "volume" is unused', range = { ["end"] = { character = 0, line = 280 }, start = { character = 22, line = 279 } }, severity = 2, source = "Elixir" }, { message = 'variable "wos_year" is unused', range = { ["end"] = { character = 0, line = 273 }, start = { character = 20, line = 272 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/extraction/matching/wos.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function init/1 required by behaviour GenServer is not implemented (in module LLMAnalysis.Flows.FlowManagement.ConcurrencyManager).\n\nWe will inject a default implementation for now:\n\n def init(init_arg) do\n {:ok, init_arg}\n end\n\nYou can copy the implementation above or define your own that converts the arguments given to GenServer.start_link/3 to the server state.\n", range = { ["end"] = { character = 0, line = 1 }, start = { character = 0, line = 0 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/flows/flow_management/concurrency_manager.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "module attribute @models was set but never used", range = { ["end"] = { character = 0, line = 10 }, start = { character = 2, line = 9 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/flows/handlers/simple_anthropic.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "fp" is unused', range = { ["end"] = { character = 0, line = 169 }, start = { character = 62, line = 168 } }, severity = 2, source = "Elixir" }, { message = 'variable "results" is unused', range = { ["end"] = { character = 0, line = 73 }, start = { character = 4, line = 72 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/job_data/structured_result.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "attempt" is unused', range = { ["end"] = { character = 0, line = 5 }, start = { character = 33, line = 4 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/workers/structuring.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "unused require Logger", range = { ["end"] = { character = 0, line = 3 }, start = { character = 2, line = 2 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/llm_analysis/workers/unstructured.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "default values for the optional arguments in the private function load_ris_in_dir!/2 are never used", range = { ["end"] = { character = 0, line = 676 }, start = { character = 7, line = 675 } }, severity = 2, source = "Elixir" }, { message = "function load_ris_in_dir/2 is unused", range = { ["end"] = { character = 0, line = 687 }, start = { character = 7, line = 686 } }, severity = 2, source = "Elixir" }, { message = "function start/0 is unused", range = { ["end"] = { character = 0, line = 34 }, start = { character = 7, line = 33 } }, severity = 2, source = "Elixir" }, { message = 'variable "step_3c_labels" is unused', range = { ["end"] = { character = 0, line = 134 }, start = { character = 4, line = 133 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/proj_utils.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "pid" is unused', range = { ["end"] = { character = 0, line = 143 }, start = { character = 12, line = 142 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/requests/llm/anthropic.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function server_info/2 is unused", range = { ["end"] = { character = 0, line = 614 }, start = { character = 7, line = 613 } }, severity = 2, source = "Elixir" }, { message = 'variable "from" is unused', range = { ["end"] = { character = 0, line = 215 }, start = { character = 40, line = 214 } }, severity = 2, source = "Elixir" }, { message = 'variable "reason" is unused', range = { ["end"] = { character = 0, line = 314 }, start = { character = 16, line = 313 } }, severity = 2, source = "Elixir" }, { message = 'variable "s" is unused', range = { ["end"] = { character = 0, line = 389 }, start = { character = 9, line = 388 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/requests/server.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = 'variable "x" is unused', range = { ["end"] = { character = 0, line = 74 }, start = { character = 6, line = 73 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/statistics/performance/common.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { message = "function get_arguments/1 is unused", range = { ["end"] = { character = 0, line = 416 }, start = { character = 7, line = 415 } }, severity = 2, source = "Elixir" }, { message = "function inspect_path/1 is unused", range = { ["end"] = { character = 0, line = 431 }, start = { character = 7, line = 430 } }, severity = 2, source = "Elixir" }, { message = "unused require Logger", range = { ["end"] = { character = 0, line = 109 }, start = { character = 2, line = 108 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 111 }, start = { character = 36, line = 110 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 160 }, start = { character = 34, line = 159 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 290 }, start = { character = 19, line = 289 } }, severity = 2, source = "Elixir" }, { message = 'variable "data" is unused', range = { ["end"] = { character = 0, line = 333 }, start = { character = 19, line = 332 } }, severity = 2, source = "Elixir" }, { message = 'variable "tag" is unused', range = { ["end"] = { character = 0, line = 131 }, start = { character = 33, line = 130 } }, severity = 2, source = "Elixir" }, { message = 'variable "tag_data" is unused', range = { ["end"] = { character = 0, line = 420 }, start = { character = 20, line = 419 } }, severity = 2, source = "Elixir" } }, uri = "file:////lib/xml/handlers/pubmed.ex" } }
[DEBUG][2026-06-18 14:06:03] .../vim/lsp/rpc.lua:391 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 70, value = { kind = "end" } } }
I'm still hesitant to suggest this as a bug in case there's still some lurking environment clashes since updating to 1.20.1, but I'm not sure what else to try currently.
I have the following snippet, where a binary is incorrectly being passed to get_first/2, which expects a %RIS.Record{}, and an unused argument (this_ris).
On change, both warnings are flagged in my editor (Neovim, expert tested using 0.1.4 and 0.1.5, Elixir 1.20.1). On save, however, only the latter type incompatibility is reported and the former unused variable is not flagged.
Sorry it's not the clearest what is happening in this clip, but first I make a change deleting two spaces, then write it, so that the first warning disappears when both should persist. Repeating the sequence, I make a minor edit adding a space, the warning reappears, then disappears after write.
e1.mp4
If it is helpful, you can see in the attached debug logs the mismatching errors (change first, then save after a short amount of time). After didChange there is a warning for variable "this_ris" is unused, but it does not appear after didSave. I have just reinstalled everything to be sure, and cleared expert's caches. A few restarts ago the discrepancy was actually different - the unused variable would always show, but the type error would only show after a change and not after saving. Here are the logs.
I'm still hesitant to suggest this as a bug in case there's still some lurking environment clashes since updating to 1.20.1, but I'm not sure what else to try currently.