🤮

nvim-treesitterで謎のエラーが発生したらruntimepathを見ると良いかもしれない

2022/09/20に公開

https://zenn.dev/dog/articles/jetpack_intro

Neovimのプラグインマネージャを vim-plug から vim-jetpack に変更してみたところ、 nvim-treesitter のエラーが出るようになってしまいました。
エラーの内容と解消の記録をこちらに残します。

事象

jetpackの説明に従って設定を書き換えてみたところ、.vimファイルを開いたときに以下のエラーが発生するようになりました。

BufReadPost Autocommands for "*" の処理中にエラーが検出されました:
Error executing lua callback: ...ar/neovim/HEAD-647da34_1/share/nvim/runtime/filetype.lua:20: Vim(append):Error executing lua callback: ...47da34_1/share/nvim/runtime/lua/vim/treesitter/query.lua:218: query: invalid structure at position 23 for language vim

設定ファイルを以下の「vim-jetpackとnvim-treesitterを読み込むだけ」の最小構成にしても発生してしまいました。

packadd vim-jetpack
call jetpack#begin()
Jetpack 'tani/vim-jetpack', { 'opt': 1 }
Jetpack 'nvim-treesitter/nvim-treesitter'
call jetpack#end()

lua require('nvim-treesitter.configs').setup({ highlight = { enable = true } })

vim-jpで質問したのですが、他の方の環境では再現できず、逆に手許のNeovim本体やtreesitterのバージョンを調整しても解消しなかったため、ローカル環境の問題という線が濃厚になりました。

原因

runtimepathに含まれている~/.local/share/nvim/siteディレクトリに、古い(半年以上前の)parser/parser-infoディレクトリが残っていて、これが読まれていたことが原因でした。


エラー発生当時の~/.local/share/nvim/site

これでは他の方の環境で再現するわけがないのでした…。

また、vim-plugのときに発生しなかった理由ですが、runtimepathの順序が関係していたようです:

  • vim-plug:プラグインのディレクトリが~/.local/share/nvim/siteより先 → nvim-treesitterのディレクトリ内の最新のparserが読み込まれる
  • vim-jetpack:プラグインのディレクトリが~/.local/share/nvim/siteより後 → ~/.local/share/nvim/siteに入っていた古いparserが読み込まれる

原因となったファイルは存在していたものの、読み込み順序の関係で、たまたま問題が隠れていたということですね。

というわけで、~/.local/share/nvim/siteディレクトリ内の古いparser/parser-infoを削除し、エラーを消すことができました。
そもそも半年前にこれらのディレクトリを作成していた理由は謎のままですが…。

結論

treesitterはruntimepath内のparserディレクトリにあるクエリを使ってパースします(:h treesitter-parser)。
挙動がおかしくなったら:echo &runtimepathして確認してみよう!

参考

以下のissue commentで「treesitterを最新にして、それでも直らなければruntimepathに古いパーサやクエリがあるかもしれない」と書かれていたのがドンピシャでした。
https://github.com/nvim-treesitter/nvim-treesitter/issues/2423#issuecomment-1026136143

Discussion