anomalyco / anomalyco/opencode
LSP diagnostics waits hardcoded at 5s/10s: slow servers return no diagnostics, indistinguishable from a clean file
@jlongster is already working on this.
Since Aug 8, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
The diagnostics wait timeouts in packages/opencode/src/lsp/client.ts are hardcoded at 5s (document) and 10s (full). For language servers that need longer to parse a translation unit, the client always gives up first and returns no diagnostics — which is indistinguishable from "the file is clean".
This is a correctness problem rather than a performance one: an agent consuming the LSP cannot tell "no problems found" from "we stopped waiting", so it reports false confidence or stops trusting the tool.
// packages/opencode/src/lsp/client.ts:14-15
const DIAGNOSTICS_DOCUMENT_WAIT_TIMEOUT_MS = 5_000
const DIAGNOSTICS_FULL_WAIT_TIMEOUT_MS = 10_000
Environment
- opencode 1.18.4 (also reproduced against
dev@ 284214c) - clangd 21.1.8, Linux x64
- Unreal Engine 5 game project, 23,382-entry
compile_commands.json
Reproduction
Any C++ file in a large Unreal project. One translation unit pulls in ~3,764 transitive headers, and clangd needs roughly 20s to parse it — measured directly over stdio LSP, independent of opencode:
| query | time |
|---|---|
| first open of a UE file (cold) | 19–25s |
| same file again, still open | 0.00s |
| a sibling file in the same module | 19.03s |
Against opencode:
$ opencode debug lsp diagnostics /path/to/HGGameUserSettings.cpp
{
"/path/to/.clangd": []
}
The requested file is absent from the result entirely, after ~11s — consistent with 5s + 10s. The same file checked with the real compiler (clang++ -fsyntax-only, using the flags from compile_commands.json) compiles cleanly, and a deliberately broken variant reports its error correctly, so clangd and the configuration are both fine.
Not caused by configuration
Ruled out by measurement:
- Compile database staleness — 442 of 452 files present; clangd interpolates flags for the rest and returns correct symbols.
- Database size — scoping it 8.5× (23,382 → 2,741 entries) moved parse time only 27.1s → 24.5s.
.clangdforce-include — removing it gives 14.2s → 10.5s and reintroduces 82 false errors. Still at the threshold.--pch-storage=memory— no change (13.9s).
There is no configuration option to extend the wait.
Related
- #23982 — LSP initialize timeout too short for Java/Gradle (~15s vs ~114s needed). Same class of problem on a different constant, which suggests this isn't specific to C++ or to Unreal.
Suggested fix
Make the two waits configurable per LSP server, defaulting to the current constants so nothing changes for anyone who doesn't opt in:
"lsp": {
"clangd": {
"command": ["clangd", "--compile-commands-dir=..."],
"timeout": { "document": 60000, "full": 120000 }
}
}
With that applied locally, the same command returns the real diagnostic in 13s:
Error [3:13] Use of undeclared identifier 'this_symbol_does_not_exist'
I have a working patch (~35 lines across 5 files) and am happy to open a PR against this issue.
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.
Assessment
This issue has not been assessed yet.