Description
Render.open validates window_context.context_winid at render.lua:518, then runs set_lines(), nvim_buf_clear_namespace(), highlight_contexts(), copy_extmarks() and highlight_bottom() before handing that same handle to horizontal_scroll_contexts() at render.lua:532, which calls nvim_win_call on it.
The window can close in between. set_lines() writes vim.bo[bufnr].modifiable, which fires OptionSet; any handler that closes a window during that event can take the context float with it, since it is relative='win'. The check at 518 is real but too early to cover the use at 532.
The guard at treesitter-context.lua:104 does not help either: it validates winid, before context.get() and the whole render.
At the point of failure winid is still valid and context_winid is not, so the id in the message is the context float.
Neovim version
NVIM v0.12.4, LuaJIT 2.1.1774638290
Expected behavior
A context window closing mid-render aborts that render quietly, the way render.lua:518 already handles the same window being gone.
Actual behavior
vim.schedule callback: .../render.lua:382: Invalid window id: 1003
stack traceback:
[C]: in function 'nvim_win_call'
.../render.lua:382: in function 'horizontal_scroll_contexts'
.../render.lua:532: in function 'open'
.../treesitter-context.lua:120: in function 'f'
.../treesitter-context.lua:60: in function <.../treesitter-context.lua:40>
Reproduced on master f3061339.
Minimal config
local plugins = {
ts = 'https://github.com/nvim-treesitter/nvim-treesitter',
ts_context = 'https://github.com/nvim-treesitter/nvim-treesitter-context',
}
for name, url in pairs(plugins) do
local install_path = '/tmp/nvim/site/'..name
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system { 'git', 'clone', '--depth=1', url, install_path }
end
vim.o.runtimepath = install_path..','..vim.o.runtimepath
end
require('treesitter-context').setup({})
-- A file deep enough to have a context, written here so the repro is one file.
local body = {}
for i = 1, 80 do
body[#body + 1] = (' local x%d = %d'):format(i, i)
end
vim.fn.writefile(
vim.list_extend({
'local function outer()',
' local function middle()',
' local function inner()',
}, vim.list_extend(body, { ' end', ' end', 'end' })),
'/tmp/nvim/sample.lua')
-- Stand-in for whatever closed the window in the wild: fires once, during the
-- render, from the 'modifiable' toggle in set_lines().
local fired = false
vim.api.nvim_create_autocmd('OptionSet', {
pattern = 'modifiable',
callback = function()
if fired or #vim.api.nvim_list_wins() < 2 then return end
fired = true
pcall(vim.api.nvim_win_close, vim.api.nvim_get_current_win(), true)
end,
})
Steps to reproduce
nvim --clean -u minimal.lua /tmp/nvim/sample.lua
:vsplit
60G
:messages
The OptionSet autocmd is a stand-in that makes the timing deterministic. This started from an organic occurrence in a large config, which I could not isolate to a specific plugin; the autocmd reproduces the same traceback on demand.
Suggested fix
local function horizontal_scroll_contexts(winid, context_winid)
if not api.nvim_win_is_valid(winid) or not api.nvim_win_is_valid(context_winid) then
return
end
Verified against f3061339: the repro is clean with this applied, and contexts still render normally. Guarding only winid is not enough, the error moves to the next line.
Description
Render.openvalidateswindow_context.context_winidatrender.lua:518, then runsset_lines(),nvim_buf_clear_namespace(),highlight_contexts(),copy_extmarks()andhighlight_bottom()before handing that same handle tohorizontal_scroll_contexts()atrender.lua:532, which callsnvim_win_callon it.The window can close in between.
set_lines()writesvim.bo[bufnr].modifiable, which firesOptionSet; any handler that closes a window during that event can take the context float with it, since it isrelative='win'. The check at 518 is real but too early to cover the use at 532.The guard at
treesitter-context.lua:104does not help either: it validateswinid, beforecontext.get()and the whole render.At the point of failure
winidis still valid andcontext_winidis not, so the id in the message is the context float.Neovim version
NVIM v0.12.4, LuaJIT 2.1.1774638290Expected behavior
A context window closing mid-render aborts that render quietly, the way
render.lua:518already handles the same window being gone.Actual behavior
Reproduced on master
f3061339.Minimal config
Steps to reproduce
nvim --clean -u minimal.lua /tmp/nvim/sample.lua:vsplit60G:messagesThe
OptionSetautocmd is a stand-in that makes the timing deterministic. This started from an organic occurrence in a large config, which I could not isolate to a specific plugin; the autocmd reproduces the same traceback on demand.Suggested fix
Verified against
f3061339: the repro is clean with this applied, and contexts still render normally. Guarding onlywinidis not enough, the error moves to the next line.