LuaLS / LuaLS/lua-language-server

noisy `-32801` ("Content Modified") errors

未關閉
#3,420 4 則留言 6 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

bug
主要語言
Lua
星號
4.4k
分支
442
PR 合併指標
30 天內沒有已合併 PR

描述

### How are you using the lua-language-server?

NeoVim

### Which OS are you using?

MacOS

### What is the issue affecting?

Other

### Expected Behaviour

In the request-completion path, when the server has computed a result against document version *V*, return that result regardless of whether `didChange` for *V+1* (or later) has since arrived. Only return `-32801` if the document
modification was genuinely external / out-of-band — which is rare in normal usage and not what `didChange` represents.

If pre-empting in-flight requests on `didChange` is desired as an optimization, the spec-compliant signal is for the *client* to send `$/cancelRequest`. The server should not unilaterally short-circuit valid in-flight work with `-32801`.

Per the spec, the client is supposed to handle staleness via cancellation. With `lua-language-server` pre-empting that decision and erroring instead:

- Clients that handle `-32801` strictly as an error end up logging spurious errors (cf. [neovim/neovim#40208](https://github.com/neovim/neovim/issues/40208)).
- Clients that *could* have used the older-version result (perfectly valid per the spec — "even computed on an older state might still be useful") never get the chance.
- Clients that wanted to cancel can no longer rely on `$/cancelRequest` semantics because the server has already aborted on its own initiative.

### Actual Behaviour

Sending a fast sequence of `didChange`s while semantic-tokens requests are in flight causes the server to error every in-flight request with:

```json
{ "code": -32801, "message": "Content modified." }
```

even though the modification was delivered through normal `didChange` notifications, not "outside normal conditions."

### Reproduction steps

1. Open a Lua file in any LSP-capable editor that requests `semanticTokens/full` (e.g. Neovim 0.12+).
2. Start typing across multiple lines, fast enough that successive `didChange` notifications outpace the server's processing.
3. Observe: every in-flight semantic-tokens request comes back with `-32801 Content modified.` instead of a (possibly stale) result.

### Additional Notes

`lua-language-server` returns LSP error `-32801` ("Content Modified") in response to `textDocument/semanticTokens/full` (and likely other requests) whenever a `textDocument/didChange` notification arrives before the response is sent.
This contradicts the LSP specification, which explicitly forbids using `-32801` for content changes detected in *unprocessed messages* — i.e. for the exact case currently being signaled.

What the spec says:

[LSP §responseError.code](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#responseError) (specifically the `ContentModified = -32801` entry):

> The server detected that the content of a document got modified outside normal conditions. **A server should NOT send this error code if it detects a content change in its unprocessed messages.** The result even computed on an older
state might still be useful for the client.
>
> If a client decides that a result is not of any use anymore the client should cancel the request.

So the intended semantics are:

- `-32801` is for "out-of-band" content modification (e.g., the file on disk changed in a way the server can't reconcile with its in-flight state).

### Log File

_No response_

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

首先追蹤 textDocument/semanticTokens/full 請求路徑,以及 textDocument/didChange 通知如何影響處理中的請求。將該行為與 LSP responseError.code 規範進行比較;當正常排隊的文件變更不再產生 -32801,而真正的外部修改仍然可以產生該錯誤時,即表示完成。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
lua, neovim
領域
devtools
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
冷清
描述清晰度
基本清楚
新手友好度
48/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。