Code actions not working for typescript-language-server

Hi there. Happy holidays to everyone.

I’d like to know if I’m missing something in my configuration to make typescript-language-server’s code actions work, or if I’m getting wrong the idea of how code actions should work on Neovim as a whole.

The typescript-language-server documentation says (here) that the server offers some code actions including removeUnused. When I try to test by creating an unused variable and I put my cursor on that variable and try to trigger the vim.lsp.buf.code_action, it says “No code actions available”. I try to place the cursor on every place I think of could have a code action available, but I keep getting the same message.

The output of :LspInfo seems to be ok:

 Language client log: /Users/yusuph/.local/state/nvim/lsp.log
 Detected filetype:   typescriptreact
 2 client(s) attached to this buffer: 
 Client: tsserver (id: 1, bufnr: [1])
 	filetypes:       javascript, javascriptreact, javascript.jsx, typescript, typescriptreact, typescript.tsx
 	autostart:       true
 	root directory:  /Users/yusuph/Documents/Repos/bla/bla
 	cmd:             typescript-language-server --stdio
 Client: diagnosticls (id: 2, bufnr: [1])
 	filetypes:       javascript, javascriptreact, typescript, typescriptreact, json, css, scss, markdown
 	autostart:       true
 	root directory:  /Users/yusuph/Documents/Repos/bla/bla
 	cmd:             diagnostic-languageserver --stdio
 Configured servers list: jsonls, diagnosticls, tsserver, html, cssls

If I try with :lua print(vim.inspect(vim.lsp.buf_get_clients()[1].server_capabilities)) I get:

-- More output here.
codeActionProvider = {
      codeActionKinds = { "source.fixAll.ts", "source.removeUnused.ts", "source.addMissingImports.ts", "source.organizeImports.ts", "quickfix", "refactor" }
-- More output here.

However, the output of LspLog shows the following message:

[START][2022-12-27 07:53:09] LSP logging initiated
[WARN][2022-12-27 07:53:09] .../lua/vim/lsp.lua:96	"method textDocument/codeAction is not supported by any of the servers registered for the current buffer"

So it seems to be recognizing the code actions that the server offers on one place, but on the logs it seems to not recognize code actions at all. Is this the expected behavior?

I’ve just updated Neovim to version 0.8.1, lspconfig and typescript-language-server to the latest version. My current LSP configuration si the following:

-- -----------------------------------------------
-- PLUGIN: Nvim Lspconfig

local nvim_lsp = require('lspconfig')
local util = require 'lspconfig/util'

-- Global diagnostic mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions.
local opts = { noremap=true, silent=true }
vim.keymap.set('n', '<leader>ld', vim.diagnostic.open_float, opts)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
vim.keymap.set('n', '<space>ll', vim.diagnostic.setloclist, opts)

-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
  -- Enable completion triggered by <c-x><c-o>
  vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')

  -- Mappings.
  -- See `:help vim.lsp.*` for documentation on any of the below functions
  local bufopts = { noremap=true, silent=true, buffer=bufnr }
  vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts)
  vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
  vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
  vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts)
  vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
  vim.keymap.set('n', '<leader>ls', vim.lsp.buf.signature_help, bufopts)
  vim.keymap.set('n', '<leader>lt', vim.lsp.buf.type_definition, bufopts)
  vim.keymap.set('n', '<leader>lr', vim.lsp.buf.rename, bufopts)
  vim.keymap.set('n', '<leader>la', vim.lsp.buf.code_action, bufopts)
  vim.keymap.set('n', '<leader>lf', function() vim.lsp.buf.format { async = true } end, bufopts)
  vim.keymap.set('n', '<leader>lwa', vim.lsp.buf.add_workspace_folder, bufopts)
  vim.keymap.set('n', '<leader>lwr', vim.lsp.buf.remove_workspace_folder, bufopts)
  vim.keymap.set('n', '<leader>lwl', function()
  end, bufopts)

-- Default time to debouce text change events.
local default_debouce_time = 150

local capabilities = require('cmp_nvim_lsp').default_capabilities()

-- -----------------------------------------------
-- CONFIG: tsserver
-- Installed globally via npm: typescript-language-server.

  on_attach = on_attach,
  capabilities = capabilities,
  flags = {
    debounce_text_changes = default_debouce_time,
  init_options = {
    preferences = {
      disableSuggestions = true,

I’d suggest to use GitHub - jose-elias-alvarez/typescript.nvim: A Lua plugin, written in TypeScript, to write TypeScript (Lua optional). because it solves the configuration problem for you.

Thanks, I’ll give it a try and let you know.

I think you should provide the ts/js file.
Does your file is a module?
If not, try to add a export

A suggestion: You can test lsp in vscode.

Answer can be found here.