fix(lsp): show meaningful error on invalid completion response #39445

Problem: vim.NIL is truthy in Lua, so `#(result.items or result)`
crashes on `#vim.NIL` when servers return null.

Solution: skip spec-allowed result=null silently, raise an error
on items=null with the server name.

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
This commit is contained in:
glepnir
2026-04-28 22:18:37 +08:00
committed by GitHub
parent c06e3d6f81
commit b9431b340f
2 changed files with 25 additions and 1 deletions

View File

@@ -1004,7 +1004,13 @@ local function trigger(bufnr, clients, ctx)
end
local result = response.result
if result and #(result.items or result) > 0 then
if type(result) == 'table' and result.items == vim.NIL then
error(
('%s: completion response has items=null, expected CompletionItem[]'):format(
client and client.name or 'UNKNOWN'
)
)
elseif result and result ~= vim.NIL and #(result.items or result) > 0 then
Context.isIncomplete = Context.isIncomplete or result.isIncomplete
local encoding = client and client.offset_encoding or 'utf-16'
local client_matches, tmp_server_start_boundary

View File

@@ -1182,6 +1182,24 @@ describe('vim.lsp.completion: protocol', function()
eq({ triggerKind = 2, triggerCharacter = 'h' }, exec_lua('return _G.params.context'))
end)
end)
it('errors on invalid items=null in completion response #39400', function()
create_server('dummy', {
isIncomplete = false,
items = vim.NIL,
})
feed('ih')
local err = t.pcall_err(function()
exec_lua(function()
vim.api.nvim_win_set_cursor(0, { 1, 1 })
vim.lsp.completion.get()
vim.wait(1000, function()
return false
end)
end)
end)
t.matches('items=null', err)
end)
end)
describe('vim.lsp.completion: integration', function()