LuaLS / LuaLS/lua-language-server
Request: Limit "Fields cannot be injected" to exact classes
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?
Windows
### What is the issue affecting?
Annotations
### Expected Behaviour
The [docs say](https://luals.github.io/wiki/annotations/#class):
> Marking the class as (exact) means fields cannot be injected after the definition.
So when I use `@class`, I expect to not get any injection warnings unless I use `(exact)`. I see this came up before in #2710, so I'd add: I should be able to get a warning for injections in exact classes while silencing warnings in non-exact classes.
### Actual Behaviour
Any time I add a field outside of the constructor (and sometimes even ones that are defined in my class constructor), I get this warning:
> Fields cannot be injected into the reference of `ClassX` for `field_y`. To do so, use `---@class` for `instance_z`.
The `@class` annotation makes lua too strict. I'm using lua because I _want_ to be able to inject fields.
Using annotations has multiple effects:
1. It improves completion.
1. It improves symbol lookups like goto definition.
1. It does type checking.
But it's not great that adding annotations to get 1+2 results in tons of warnings from 3.
I understand that people may not want to add `(exact)` all over their codebase, but I don't want to add `---@field [any] any` to all of mine.
I'd propose a change to diagnostic flags to allow independently controlling these two cases:
* `inject-field`: suppress inject field diagnostic for non-exact classes.
* `inject-field-exact`: suppress inject field diagnostic for exact classes.
### Reproduction steps
Using neovim and installed luals with Mason. Version: `pkg:github/luals/lua-language-server@3.17.1`
```lua
-- Stripped-down version of https://github.com/rxi/classic/blob/master/classic.lua with an annotation added to be close to real-world class usage.
--
-- classic
--
-- Copyright (c) 2014, rxi
--
-- This module is free software; you can redistribute it and/or modify it under
-- the terms of the MIT license. See LICENSE for details.
--- @class Object
local Object = {}
Object.__index = Object
function Object:new()
end
function Object:extend()
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
end
function Object:__call(...)
local obj = setmetatable({}, self)
obj:new(...)
return obj
end
-- /end classic
--- @class Item : Object
local Item = Object:extend()
function Item:new(id, category)
self.id = id
self.category = category
self.count = 0
end
function Item:Print()
print("Item", self.id, self.category, self.count)
end
--- @param item Item
function FlagDebugItem(item)
item:Print() -- with the annotation, this completes. Yay!
item.is_cheater = true -- Warning :( "Fields cannot be injected into the reference of `Item` for `is_cheater`."
end
```
If I configure luals to add `inject-field` to the `Lua.diagnostics.disable` list, then the warning goes away. But the warning doesn't come back when I make Item an exact class with this annotation: `--- @class (exact) Item : Object`
**Workaround:** Add a fake field of any type:
```lua
--- @class Item : Object
--- @field [any] any
local Item = Object:extend()
```
### Additional Notes
_No response_
### Log File
```
[WARN][2026-02-23 11:41:41] ...lsp/handlers.lua:564 "More than 100000 files have been scanned. The current scanned directory is `D:\\code\\project\\br`. Please see the [FAQ](https://luals.github.io/wiki/faq/#how-can-i-improve-startup-speeds) to see how you can include fewer files. It is also possible that your [configuration is incorrect](https://luals.github.io/wiki/faq#why-is-the-server-scanning-the-wrong-folder)."
[WARN][2026-02-23 14:32:31] .../lua/vim/lsp.lua:52 "method textDocument/typeDefinition is not supported by any of the servers registered for the current buffer"
[START][2026-02-23 15:29:24] LSP logging initiated
[ERROR][2026-02-23 15:29:24] ...m/lsp/client.lua:620 "LSP[lua_ls]" "Cannot find request with id 125 whilst attempting to cancel"
```
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 running the provided NeoVim reproduction with LuaLS 3.17.1 and compare `@class` with `@class (exact)`. Then trace how the `inject-field` diagnostic is applied; done means non-exact and exact classes can be controlled independently as proposed, while the documented completion and lookup behavior remains available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100