vuejs/language-tools

Neovim: TypeError: server.workspaceFolders.keys is not a function or its return value is not iterable\n at createLs (~/.local/share/nvim/mason/packages/vue-language-server/node_modules/@vue/language-server/lib/hybridModeProject.js:94:193)

Napam opened this issue · 10 comments

Vue - Official extension or vue-tsc version

2.0.29

VSCode version

None, Im using Neovim 0.10.1

Vue version

3.4.29

TypeScript version

5.4.0

System Info

System:
    OS: macOS 14.6.1
    CPU: (10) arm64 Apple M2 Pro
    Memory: 102.89 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.11.1/bin/yarn
    npm: 10.8.1 - ~/.nvm/versions/node/v20.11.1/bin/npm
    pnpm: 9.1.1 - ~/.nvm/versions/node/v20.11.1/bin/pnpm
  Browsers:
    Chrome: 127.0.6533.120
    Edge: 113.0.1774.57
    Safari: 17.6

Steps to reproduce

Attempt to start volar lsp on a .vue file

What is expected?

The LSP to not fail

What is actually happening?

I get the following error:

[ERROR][2024-08-18 17:46:41] .../vim/lsp/rpc.lua:770    "rpc"   "/Users/naphat/.local/share/nvim/mason/bin/vue-language-server" "stderr"        "/Users/naphat/.local/share/nvim/mason/packages/vue-language-server/node_modules/@vue/language-server/lib/hybridModeProject.js:94
        return (0, language_service_1.createLanguageService)(language, server.languageServicePlugins, (0, simpleProject_1.createLanguageServiceEnvironment)(server, [...server.workspaceFolders.keys()]), project);
                                                                                                                                                                                                ^

TypeError: server.workspaceFolders.keys is not a function or its return value is not iterable
    at createLs (/Users/naphat/.local/share/nvim/mason/packages/vue-language-server/node_modules/@vue/language-server/lib/hybridModeProject.js:94:193)
    at async Object.getLanguageService (/Users/naphat/.local/share/nvim/mason/packages/vue-language-server/node_modules/@vue/language-server/lib/hybridModeProject.js:50:24)
    at async updateDiagnostics (/Users/naphat/.local/share/nvim/mason/packages/vue-language-server/node_modules/@vue/language-server/node_modules/@volar/language-server/lib/features/languageFeatures.js:628:33)
    at async updateDiagnosticsBatch (/Users/naphat/.local/share/nvim/mason/packages/vue-language-server/node_modules/@vue/language-server/node_modules/@volar/language-server/lib/features/languageFeatures.js:624:13)

Node.js v20.11.1

Any additional comments?

Here is my relevant neovim config:

local vue_language_server_path = mason_registry
  .get_package("vue-language-server")
  :get_install_path() .. "/node_modules/@vue/language-server"

lspconfig.tsserver.setup({
  -- root_dir = require("lspconfig.util").root_pattern("package.json"),
  init_options = {
    plugins = {
      {
        name = "@vue/typescript-plugin",
        location = vue_language_server_path,
        languages = { "vue" },
      },
    },
  },
  filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
  -- single_file_support = false,
})

lspconfig.volar.setup({})

I have based this on the informaiton provided in the README of this repository.

The directory I am starting neovim form is a base "npm create vue@latest" directory which looks like this:

README.md
env.d.ts
index.html
lvim.lunaruser
node_modules
package-lock.json
package.json
public
src
tsconfig.app.json
tsconfig.json
tsconfig.node.json
tsconfig.vitest.json
vite.config.ts
vitest.config.ts

It seems to me that this is due to a breaking change introduced by @volar/language-server on version 2.4.0-alpha.19, specifically by this commit which changed the type of server.workspaceFolders.

I think this version is pulled because the dependency is declared in package.json as "@volar/language-server": "~2.4.0-alpha.18". I believe the tilde would make it match -alpha.19, which contains the breaking change.

This might only affect vim because the package manager just runs npm install, unlike VS Code where I think it would be packaged in a way that the dependencies are pinned stronger.

As a workaround, if you're using Mason, you can cd ~/.local/share/nvim/mason/packages/vue-language-server/node_modules/@vue/language-server, edit package.json, remove the tildes on line 18 and 19, then run npm install.

@iro-miya Thank you very much! I did exactly as you told and that worked. Your diagnosis was spot on.

Hi @johnsoncodehk can we pin volar's version for this reason?

This is caused by upgrading @vue/language-server 2.4.0-alpha.18 to 2.4.0-alpha.19 in node_modules. Can you confirm that upgrading to 2.4.0-alpha.20 can solve it?

@RayGuo-ergou Yes, we should pin it if we use the Volar alpha version in the future.

@johnsoncodehk checked, pinned 2.4.0-alpha.20 version solve that issue

@johnsoncodehk I also found @vue/language-server v2.0.29 with @volar/language-core & @volar/language-server 2.4.0-alpha.20 works fine.
But, when I run npm install now, @volar/language-core & @volar/language-server 2.4.0 (not alpha) are downloaded and the error "TypeError: server.workspaceFolders.keys is not a function or its return value is not iterable" happens again.

I can avoid this error by using following tentative package.json to install @vue/language-server with pinning @volar/language-core & @volar/language-server to 2.4.0-alphat.20.

{
    "name":"",
    "dependencies":{
        "@vue/language-server":"2.0.29",
        "typescript":"^5.4.2"
    },
    "overrides": {
        "@volar/language-core": "2.4.0-alpha.20",
        "@volar/language-server": "2.4.0-alpha.20"
    }
}

For me, if the next release of @vue/language-server (probably 2.0.30) solves this, I can wait for it.

I'm using emacs with eglot but having the same issues. I installed the language server globally like this:

yarn global add @vue/language-server@next @vue/typescript-plugin@next http-server typescript typescript-language-server

which installs the following:

info "@vue/language-server@2.0.26-alpha.2" has binaries:
   - vue-language-server
info "http-server@14.1.1" has binaries:
   - http-server
info "typescript@5.5.4" has binaries:
   - tsc
   - tsserver
info "typescript-language-server@4.3.3" has binaries:
   - typescript-language-server

but starting the server gives this error:

[stderr]  /Users/garyo/.config/yarn/global/node_modules/@vue/language-server/lib/hybridModeProject.js:59
[stderr]          server.onDidChangeWatchedFiles(({ changes }) => {
[stderr]                 ^
[stderr]  
[stderr]  TypeError: server.onDidChangeWatchedFiles is not a function
[stderr]      at initialize (/Users/garyo/.config/yarn/global/node_modules/@vue/language-server/lib/hybridModeProject.js:59:16)
[stderr]      at Object.getLanguageService (/Users/garyo/.config/yarn/global/node_modules/@vue/language-server/lib/hybridModeProject.js:21:17)
[stderr]      at updateDiagnostics (/Users/garyo/.config/yarn/global/node_modules/@volar/language-server/lib/features/languageFeatures.js:682:47)
[stderr]      at updateDiagnosticsBatch (/Users/garyo/.config/yarn/global/node_modules/@volar/language-server/lib/features/languageFeatures.js:678:19)

and if I comment out that code in hybridModeProject.js then I get the "server.workspaceFolders.keys is not a function" error.
I don't know how to pin dependencies with yarn global add -- anyone have ideas?

@johnsoncodehk 2.4.0-alpha.20 works for me too. Thanks!

@johnsoncodehk @vue/language-server v2.1.0 solves this problem. Thank you so much!!