anomalyco / anomalyco/opencode

LSP diagnostics waits hardcoded at 5s/10s: slow servers return no diagnostics, indistinguishable from a clean file

Open
#41,218 1 comment 0 reactions 1 assignee View on GitHub

@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.
  • .clangd force-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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.