elixirneovimelixirls

Neovim+ElixirLS only working for one of my projects


I am currently playing around with Neovim and ElixirLS.

I have two very similar Phoenix projects, but the ElixirLS integration only works for one of them and I can't figure out what is the reason, especially because I don't know where the error originates from.

Here's my nvim-lspconfig configuration for Elixir:

return {
  "neovim/nvim-lspconfig",
  config = function()
    local lspconfig = require("lspconfig")

    lspconfig.elixirls.setup({
      cmd = { "elixir-ls" },
      on_attach = function(client, buffer)
        vim.api.nvim_create_autocmd("BufWritePre", {
          buffer = buffer,
          callback = function()
            vim.lsp.buf.format({ async = false })
          end
        })
      end,
      elixirLS = {
        dialyzerEnabled = false,
        fetchDeps = false
      }
    })
  end
}

For debugging purposes I check ~/.local/state/nvim/lsp.log to see what is going on. When opening an elixir file of project A, I get the following log messages:

[[START][2025-07-17 16:24:26] LSP logging initiated
[ERROR][2025-07-17 16:24:26] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Running /home/jan/.asdf/installs/elixir-ls/0.28.0/launch.sh\n"
[ERROR][2025-07-17 16:24:26] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Preferred shell is bash, relaunching\n"
[ERROR][2025-07-17 16:24:26] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Looking for asdf install\n"
[ERROR][2025-07-17 16:24:26] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "asdf executable found at /home/jan/.asdf/bin/asdf. Using ASDF_DIR=, ASDF_DATA_DIR=/home/jan/.asdf.\n"
[ERROR][2025-07-17 16:24:26] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Installing ElixirLS release v0.28.0\nRunning in /home/jan/Workspace/project-a\n"
[ERROR][2025-07-17 16:24:26] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Install complete\n"

I do the same for project B:

[START][2025-07-17 16:25:43] LSP logging initiated
[ERROR][2025-07-17 16:25:43] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Running /home/jan/.asdf/installs/elixir-ls/0.28.0/launch.sh\nPreferred shell is bash, relaunching\nLooking for asdf install\n"
[ERROR][2025-07-17 16:25:43] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "asdf executable found at /home/jan/.asdf/bin/asdf. Using ASDF_DIR=, ASDF_DATA_DIR=/home/jan/.asdf.\n"
[ERROR][2025-07-17 16:25:43] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Installing ElixirLS release v0.28.0\n"
[ERROR][2025-07-17 16:25:43] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Running in /home/jan/Workspace/project-b\n"
[ERROR][2025-07-17 16:25:43] ...p/_transport.lua:36     "rpc"   "elixir-ls"     "stderr"        "Install complete\n"

So far so good, everything looks good. When I now edit a file in project A and save it, the file gets formatted and I only get some output about elixir warnings from dependencies:

[WARN][2025-07-17 16:27:50] ...lsp/handlers.lua:564     "    warning: <%# is deprecated, use <%!-- or add a space between <% and # instead\n    │\n  1 │ <%#\n    │ ~\n    │\n    └─ lib/event_store/sql/statements/insert_events.sql.eex:1: (file)\n"
[WARN][2025-07-17 16:27:50] ...lsp/handlers.lua:564     "    warning: <%# is deprecated, use <%!-- or add a space between <% and # instead\n    │\n 24 │   <%#\n    │   ~\n    │\n    └─ lib/event_store/sql/statements/insert_events.sql.eex:24: (file)\n"
[WARN][2025-07-17 16:28:15] ...lsp/handlers.lua:564     "    warning: redefining module Mix.Tasks.Dialyzer (current version loaded from /home/jan/.cache/mix/installs/elixir-1.18.3-erts-15.2.3/fbaa1690847ff8f7acc189fd105b76b0/_build/prod/lib/dialyxir_vendored/ebin/Elixir.Mix.Tasks.Dialyzer.beam)\n    │\n  1 │ defmodule Mix.Tasks.Dialyzer do\n    │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n    │\n    └─ lib/mix/tasks/dialyzer.ex:1: Mix.Tasks.Dialyzer (module)\n"

When I do the same in project B, editing a file and saving it, I only get this:

[ERROR][2025-07-17 16:29:16] ...m/lsp/client.lua:619    "LSP[elixirls]" "Cannot find request with id 2 whilst attempting to cancel"

The file is save, but not formatted. I already figured out that this message comes from the LSP client in Neovim: https://github.com/neovim/neovim/blob/e6ce067f02ed07501093e79dc56466fada8652a1/runtime/lua/vim/lsp/client.lua#L663

I think it's only a sympton, not the root cause, but the .elixir_ls directory in project B is empty whereas it contains a build directory for project A:

$ ls -la project-a/.elixir_ls
total 12M
drwxrwxr-x 3 jan jan 4,0K Jul 17 16:27 build
-rw-rw-r-- 1 jan jan    1 Jul 17 16:27 .gitignore
-rw-rw-r-- 1 jan jan  12M Jul 17 16:31 iplt-27.3_elixir-1.18.3-test

$ ls -la project-b/.elixir_ls
total 4,0K
-rw-rw-r-- 1 jan jan 1 Jul  7 07:31 .gitignore

Both projects use the same Elixir and Erlang versions:

$ cat .tool-versions
erlang 27.3
elixir 1.18.3-otp-27

Here's my Neovim version:

$ nvim --version
NVIM v0.11.2
Build type: Release
LuaJIT 2.1.1741730670
Run "nvim -V1 -v" for more info

Does anyone have any clue why everything works fine for project-a, but doesn't for project-b?


Edit: I just realized that when I open up a file from project B in the same Neovim instance where I have project A, everthing works just fine. I thinks that's an important information for you. I open up Neovim for each project.

Terminal A:

$ nvim lib/project_a_web/router.ex

Terminal B:

$ nvim lib/project_b_web/router.ex

Solution

  • I finally found the root cause for ElixirLS not working for the existing project.

    $ MIX_ENV=test iex -S mix
    Erlang/OTP 27 [erts-15.2.3] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]
    
    ** (File.Error) could not read file "/home/jan/Workspace/project-b/config/test.exs": no such file or directory
    

    I renamed test for that project, but ElixirLS requires it. Adding config/test.exs solved the issue for me.