`vim.lsp.start` Failure For `ast-grep` Language Server When Using Sessions And `autochdir`
Problem
The ast-grep
language server fails to start when using root_markers
but works fine if a custom (and equivalent) root_dir
function is provided. This issue seems to only appear when using autochdir
and a session file where the session is restored to a buffer that is not in a project that does not contain the root marker file, and a buffer in the session is switched to that is in a project containing the root marker file.
Error Message
The error seen is:
Client ast_grep quit with exit code 2 and signal 0. Check log for errors: /Users/josh/.local/state/nvim/lsp.log
and the lsp.log
has the error:
[ERROR][2025-05-17 13:57:22] ...p/_transport.lua:36 "rpc" "ast-grep" "stderr" "Error: No ast-grep project configuration is found.\nHelp: You need to create an ast-grep project for this command. Try `sg new` to create one.\nSee also: https://ast-grep.github.io/guide/scan-project.html\n\n"
even though there is an sgconfig.yml
(one of the root_markers
) present for the project.
Workaround
Manually adding a root_dir
function, like:
local make_root_dir = function(root_markers)
local root_dir = function(bufnr, on_dir)
on_dir(vim.fs.root(bufnr, root_markers))
end
return root_dir
end
vim.lsp.config(
'ast_grep',
{
root_dir = make_root_dir({'sgconfig.yml', 'sgconfig.yaml'})
}
)
vim.lsp.enable('ast_grep')
works around the problem.
Steps to Reproduce
Setup
Create the following files somewhere (e.g. /tmp/nvim-test
)
minimal.lua
for name, url in pairs {
"https://github.com/neovim/nvim-lspconfig",
} do
local install_path = vim.fn.fnamemodify('nvim_issue/' .. name, ':p')
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system { 'git', 'clone', '--depth=1', url, install_path }
end
vim.opt.runtimepath:append(install_path)
end
local make_root_dir = function(root_markers)
local root_dir = function(bufnr, on_dir)
on_dir(vim.fs.root(bufnr, root_markers))
end
return root_dir
end
-- uncomment to work around issue:
-- vim.lsp.config(
-- 'ast_grep',
-- {
-- root_dir = make_root_dir(vim.lsp.config.ast_grep.root_markers)
-- }
-- )
vim.lsp.enable({ 'ast_grep' })
sgconfig.yml
Basic config for ast-grep
:
ruleDirs:
- rules
foo.py
A dummy file to open:
def foo():
pass
Steps to Reproduce
-
Install
ast-grep
:e.g. for macOS:
$ brew install ast-grep
-
Start
nvim
with the minimal configuration:$ cd /tmp/nvim-test $ nvim --clean -u /tmp/nvim-test/minimal.lua
-
Open
foo.py
(i.e.:e /tmp/nvim-test/foo.py
) -
Open and save some file outside of the project (e.g.
:e /tmp/bar.py | :w
) -
Save the session
:mksession /tmp/Session.vim
and quit. -
Restart
nvim
and load the saved session:$ nvim --clean -u /tmp/nvim-test/minimal.lua -S /tmp/Session.vim
-
Switch to
foo.py
(i.e.:b foo.py
or:b #
)
The error should now appear.
Uncommenting the vim.lsp.config(...)
in minimal.lua
should prevent the error.
Expected Behavior
The language server should start without errors.
Nvim Version (nvim -v)
v0.12.0-nightly+2fda267
Vim (not Nvim) Behaves the Same?
n/a
Operating System/Version
macOS 15.5
Terminal Name/Version
alacritty 0.15.1 (0c405d5)
$TERM Environment Variable
tmux-256color
Installation
Nix neovim nightly overlay: https://github.com/nix-community/neovim-nightly-overlay
Possible Cause
The issue seems to be related to the way root_dir
is specified. When root_dir
is specified as a function, the server is being initialised using vim.schedule
, but without root_dir
it is initialised immediately and there is some race-condition.
Solution
To fix this issue, we need to ensure that the root_dir
function is called before the language server is initialised. We can do this by adding a vim.schedule
call to the root_dir
function.
local make_root_dir = function(root_markers)
local root_dir = function(bufnr, on_dir)
vim.schedule(function()
on_dir(vim.fs.root(bufnr, root_markers))
end)
end
return root_dir
end
vim.lsp.config(
'ast_grep',
{
root_dir = make_root_dir({'sgconfig.yml', 'sgconfig.yaml'})
}
)
vim.lsp.enable('ast_grep')
Q: What is the issue with the ast-grep language server when using sessions and autochdir?
A: The issue is that the language server fails to start when using root_markers
but works fine if a custom (and equivalent) root_dir
function is provided. This issue seems to only appear when using autochdir
and a session file where the session is restored to a buffer that is not in a project that does not contain the root marker file, and a buffer in the session is switched to that is in a project containing the root marker file.
Q: What is the error message that is seen when the issue occurs?
A: The error seen is:
Client ast_grep quit with exit code 2 and signal 0. Check log for errors: /Users/josh/.local/state/nvim/lsp.log
and the lsp.log
has the error:
[ERROR][2025-05-17 13:57:22] ...p/_transport.lua:36 "rpc" "ast-grep" "stderr" "Error: No ast-grep project configuration is found.\nHelp: You need to create an ast-grep project for this command. Try `sg new` to create one.\nSee also: https://ast-grep.github.io/guide/scan-project.html\n\n"
even though there is an sgconfig.yml
(one of the root_markers
) present for the project.
Q: What is the workaround for this issue?
A: Manually adding a root_dir
function, like:
local make_root_dir = function(root_markers)
local root_dir = function(bufnr, on_dir)
on_dir(vim.fs.root(bufnr, root_markers))
end
return root_dir
end
vim.lsp.config(
'ast_grep',
{
root_dir = make_root_dir({'sgconfig.yml', 'sgconfig.yaml'})
}
)
vim.lsp.enable('ast_grep')
works around the problem.
Q: What are the steps to reproduce this issue?
A: The steps to reproduce this issue are:
-
Install
ast-grep
:e.g. for macOS:
$ brew install ast-grep
-
Start
nvim
with the minimal configuration:$ cd /tmp/nvim-test $ nvim --clean -u /tmp/nvim-test/minimal.lua
-
Open
foo.py
(i.e.:e /tmp/nvim-test/foo.py
) -
Open and save some file outside of the project (e.g.
:e /tmp/bar.py | :w
) -
Save the session
:mksession /tmp/Session.vim
and quit. -
Restart
nvim
and load the saved session:$ nvim --clean -u /tmp/nvim-test/minimal.lua -S /tmp/Session.vim
-
Switch to
foo.py
(i.e.:b foo.py
or:b #
)
The error should now appear.
Uncommenting the vim.lsp.config(...)
in minimal.lua
should prevent the error.
Q: What is the expected behavior?
A: The language server should start without errors.
Q: Does this issue occur in Vim (not Nvim)?
A: n/a
Q: What is the operating system and version?
A: macOS 15.5
Q: What is the terminal name and version?
A: alacritty 0.15.1 (0c405d5)
Q: What is the $TERM environment variable?
A: tmux-256color
Q: How was the installation done?
A: Nix neovim nightly overlay: https://github.com/nix-community/neovim-nightly-overlay
Q: What is the possible cause of this issue?
A: The issue seems to be related to the way root_dir
is specified. When root_dir
is specified as a function, the server is being initialised using vim.schedule
, but without root_dir
it is initialised immediately and there is some race-condition.
Q: What is the solution to this issue?
A: To fix this issue, we need to ensure that the root_dir
function is called before the language server is initialised. We can do this by adding a vim.schedule
call to the root_dir
function.
local make_root_dir = function(root_markers)
local root_dir = function(bufnr, on_dir)
vim.schedule(function()
on_dir(vim.fs.root(bufnr, root_markers))
end)
end
return root_dir
end
vim.lsp.config(
'ast_grep',
{
root_dir = make_root_dir({'sgconfig.yml', 'sgconfig.yaml'})
}
)
vim.lsp.enable('ast_grep')
This should fix the issue and allow the language server to start without errors.