Skip to content

lsp diagnostics reports a false clean (OK) when a push-only server publishes nothing for the document #15408

Description

@Ofrys-tech

Summary

lsp diagnostics returns OK with details.success: true for a file that has real diagnostics when the server never publishes for that document inside the wait budget. "No fresh publish observed" is indistinguishable from "clean" in the tool result, so an agent can be told a broken config file is fine.

Repro (custom tombi server, omp 18.8.9)

  1. ~/.omp/agent/lsp.json:
{
  "servers": {
    "tombi": {
      "command": "tombi",
      "args": ["lsp"],
      "fileTypes": [".toml"],
      "rootMarkers": ["wrangler.toml"],
      "isLinter": true
    }
  }
}
  1. wrangler.toml with two schema violations:
name = "lsp-probe"
main = "src/index.ts"
compatibility_date = 12345
unknown_field = true
  1. In a fresh session, lsp diagnostics with file="wrangler.toml" returns OK (serverName: tombi, success: true).
  2. Repeating the identical call returns the real result:
2 error(s):
# wrangler.toml
  3:22 [error] [Tombi] expected a value of type String, but found Integer (type-mismatch)
  4:1 [error] [Tombi] "unknown_field" is not allowed (key-not-allowed)

The same happens on the write path: write returns diagnostics: { server: "tombi", messages: [], summary: "OK", errored: false }, and an immediate re-run of lsp diagnostics returns the two errors.

Control: the same first call in a cold session against typescript-language-server returns real errors, so this is not a general cold-start problem in the tool.

Mechanism (read from the shipped sources)

  • src/lsp/tool.ts (diagnostics action): const minVersion = client.diagnosticsVersion → await refreshFile(client, resolved, signal) → waitForDiagnostics(client, uri, { timeoutMs, minVersion, expectedDocumentVersion }).
  • src/lsp/diagnostics.ts → waitForDiagnostics(): when client.diagnostics.get(uri) stays empty until the deadline and the pull path is unavailable (supportsDocumentDiagnostics(client) is false — tombi answers textDocument/diagnostic but does not advertise diagnosticProvider), the function returns [].
  • tool.ts then maps the empty array to OK with success: true.

Server-side trigger used here: tombi publishes diagnostics only after its background schema/config load; a document opened before that load finishes never gets a publish (verified: didOpen sent immediately after initialized → no publishDiagnostics for 12s+; with a ~1s gap → publish arrives immediately). Once the client is warm, every later call is correct.

Suggested fix

  • Track whether any publish (or successful pull) was observed for the URI during the wait. If none was, do not report clean — reuse the existing "some servers failed" warning shape, e.g. OK + no diagnostics published for <file> within <N>s, or return success: false with an explicit unverified message.
  • Consider probing textDocument/diagnostic for servers that answer pull requests without advertising diagnosticProvider (tombi does), or treating an empty pull as unverified rather than clean.

Environment

omp 18.8.9 (macOS 25.3.0, arm64), tombi 1.8.1 (tombi lsp), typescript-language-server as control.

Activity

  1. added
    bugSomething isn't working
    prio:p2Medium: important but not urgent
    toolTool behavior and integrations
    on Oct 11, 2026
  2. roboomp commented on Oct 11, 2026

    @roboomp
    Collaborator

    Looking into this, will report back with a repro.

  3. roboomp commented on Oct 11, 2026

    @roboomp
    Collaborator

    Reproduced on the current worktree: waitForDiagnostics() returns [] after the deadline with no publish and no advertised pull (packages/coding-agent/src/lsp/diagnostics.ts:320-348); lsp diagnostics then renders OK with success: true (tool.ts:401-422). Fixing the missing-evidence path, including write feedback.

  4. roboomp commented on Oct 11, 2026

    @roboomp
    Collaborator

    Fixed in #15412. A silent push-only server can no longer produce a verified clean result; focused LSP regressions passed (152 tests). The full suite remains blocked by the same interactive changelog PTY output-limit failure reproduced on clean origin/main; details are in the PR verification section.

  5. added 2 commits that reference this issue on Oct 11, 2026
    cdd910d
    e3ac18c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingprio:p2Medium: important but not urgenttoolTool behavior and integrationstriaged

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions