LuaLS / LuaLS/lua-language-server
noisy `-32801` ("Content Modified") errors
Nobody has claimed this yet.
- Dominant language
- Lua
- Stars
- 4.4k
- Forks
- 442
- PR merge metrics
- No merged PRs in 30d
Description
### 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_
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the textDocument/semanticTokens/full request path and how textDocument/didChange notifications affect in-flight requests. Compare that behavior with the LSP responseError.code specification; done means normal queued document changes no longer produce -32801, while genuinely external modifications still can.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua, neovim
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100