fix(lsp): unclear error on malformed server responses #40422

Problem:
Malformed server responses with `null` (vim.NIL) values, do not show
clear error messages.


Solution:
Assert two known, specific cases, to avoid user confusion.
This commit is contained in:
Kim A. Brandt
2026-07-12 18:52:10 +02:00
committed by GitHub
parent 58b6310adc
commit 543a96e491
4 changed files with 34 additions and 0 deletions

View File

@@ -211,6 +211,7 @@ function M.open(opts, ...)
--- @type lsp.DiagnosticRelatedInformation[]
local related_info = vim.tbl_get(diagnostic, 'user_data', 'lsp', 'relatedInformation') or {}
assert(related_info ~= vim.NIL, 'server response has invalid (null) relatedInformation')
-- Below the diagnostic, show its LSP related information (if any) in the form of file name and
-- range, plus description.
for _, info in ipairs(related_info) do

View File

@@ -83,6 +83,7 @@ end
--- @return table?
local function tags_lsp_to_vim(diagnostic, client_id)
local tags ---@type table?
assert(diagnostic.tags ~= vim.NIL, 'server response has invalid (null) tags')
for _, tag in ipairs(diagnostic.tags or {}) do
if tag == protocol.DiagnosticTag.Unnecessary then
tags = tags or {}

View File

@@ -3657,6 +3657,22 @@ describe('vim.diagnostic', function()
)
end)
it('errors when LSP relatedInformation is null', function()
matches(
'server response has invalid %(null%) relatedInformation',
pcall_err(
exec_lua,
[[
local diagnostic = _G.make_warning('Some warning', 1, 1, 1, 3)
diagnostic.user_data = { lsp = { relatedInformation = vim.NIL } }
vim.api.nvim_win_set_buf(0, _G.diagnostic_bufnr)
vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, { diagnostic })
vim.diagnostic.open_float({ header = false, scope = 'buffer' })
]]
)
)
end)
it('works with the old signature', function()
eq(
{ '1. Syntax error' },

View File

@@ -7,6 +7,8 @@ local clear = n.clear
local exec_lua = n.exec_lua
local eq = t.eq
local neq = t.neq
local matches = t.matches
local pcall_err = t.pcall_err
local create_server_definition = t_lsp.create_server_definition
@@ -300,6 +302,20 @@ describe('vim.lsp.diagnostic', function()
end)
)
end)
it('errors when diagnostic tags is null', function()
matches(
'server response has invalid %(null%) tags',
pcall_err(exec_lua, function()
vim.lsp.diagnostic.on_publish_diagnostics(nil, {
uri = fake_uri,
diagnostics = {
vim.tbl_extend('force', _G.make_error('Diagnostic', 0, 0, 0, 0), { tags = vim.NIL }),
},
}, { client_id = client_id })
end)
)
end)
end)
describe('vim.lsp.diagnostic.on_diagnostic', function()