Skip to content

gopls: add opt-in eager diagnostic clearing for agentic workflows#620

Open
alliprice wants to merge 2 commits intogolang:masterfrom
lsp-eager-invalidation:feature/eager-diagnostic-invalidation
Open

gopls: add opt-in eager diagnostic clearing for agentic workflows#620
alliprice wants to merge 2 commits intogolang:masterfrom
lsp-eager-invalidation:feature/eager-diagnostic-invalidation

Conversation

@alliprice
Copy link

Summary

Adds an opt-in eagerDiagnosticsClear setting that immediately publishes empty diagnostics for a file when its content changes (via textDocument/didChange), before reanalysis completes.

Motivation

The current debounce behavior is correct for GUI editors - it prevents diagnostic flicker while a human is typing. This default should remain unchanged.

However, LSP is increasingly used by headless agentic tools (AI coding assistants, automated refactoring systems) that consume diagnostics programmatically. For these clients, stale diagnostics between an edit and reanalysis are incorrect input to decision loops. This can cause:

  • Re-fixing already fixed errors
  • Missing newly introduced errors
  • Looping on diagnostics that no longer apply

This is not about servers being buggy - it is about different client requirements. Interactive editors need stable UI. Programmatic clients need immediate staleness signals.

Changes

  • New setting: eagerDiagnosticsClear (default: false, status: "advanced")

    • When enabled, textDocument/didChange triggers an immediate publish of empty diagnostics for the changed file
    • Server continues normal analysis pipeline
    • Fresh diagnostics arrive once reanalysis completes
  • Implementation:

    • Added EagerDiagnosticsClear to DiagnosticOptions in settings.go
    • Hooked into didModifyFiles in text_synchronization.go for FromDidChange cause
    • Reuses existing version-filtered publishFileDiagnosticsLocked pipeline
    • Because file version just changed, no existing view diagnostics match new version, so published set is naturally empty
    • Only processes files that already have diagnostics tracked
  • Tests: New integration test verifies:

    • With setting enabled: first notification after edit is an empty clear
    • With setting disabled: first notification after edit contains diagnostics (no eager clear)
  • Documentation: Updated gopls/doc/settings.md with new setting

Configuration

{
  "gopls": {
    "eagerDiagnosticsClear": false
  }
}

Setting this to true is intended for non-UI rapid-edit workflows such as agentic coding tools.

Test Plan

  1. Run existing test suite to verify no regressions in default behavior: go test ./...
  2. Run new integration test to verify eager clearing: go test -run TestEagerDiagnosticInvalidation ./gopls/internal/test/integration/diagnostics
  3. Manual verification in VS Code or other LSP client:
    • With setting disabled: observe normal debounced diagnostic updates
    • With setting enabled: observe immediate diagnostic clearing on edit

Related Work

This is part of a coordinated effort across multiple LSP server ecosystems to support agentic workflows. See: https://github.com/lsp-eager-invalidation

Similar PRs:

  • typescript-language-server (TypeScript)
  • pyright (Python)
  • rust-analyzer (Rust)

Add opt-in setting (eagerDiagnosticsClear, default: false) that immediately
publishes diagnostics for changed files in didModifyFiles when the change
originates from didChange. The existing version-filtering in
publishFileDiagnosticsLocked ensures stale view diagnostics tagged with the
previous version are excluded, producing an empty set that clears stale errors.

This prevents agentic/headless LSP clients from acting on stale diagnostics
between an edit and the completion of reanalysis. Includes settings
documentation, integration test, and schema entry.
settings.md is auto-generated from struct doc comments via
gopls/internal/doc/generate. The previous commit manually edited
settings.md with additional text not present in the source doc comment,
which would cause TestGenerated to fail.

Regenerated using: cd gopls/internal/doc/generate && go run .

The settings.go doc comment is the source of truth.
@google-cla
Copy link

google-cla bot commented Mar 4, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@alliprice alliprice force-pushed the feature/eager-diagnostic-invalidation branch from 557557e to ff54883 Compare March 4, 2026 13:03
@gopherbot
Copy link
Contributor

This PR (HEAD: ff54883) has been imported to Gerrit for code review.

Please visit Gerrit at https://go-review.googlesource.com/c/tools/+/751400.

Important tips:

  • Don't comment on this PR. All discussion takes place in Gerrit.
  • You need a Gmail or other Google account to log in to Gerrit.
  • To change your code in response to feedback:
    • Push a new commit to the branch used by your GitHub PR.
    • A new "patch set" will then appear in Gerrit.
    • Respond to each comment by marking as Done in Gerrit if implemented as suggested. You can alternatively write a reply.
    • Critical: you must click the blue Reply button near the top to publish your Gerrit responses.
    • Multiple commits in the PR will be squashed by GerritBot.
  • The title and description of the GitHub PR are used to construct the final commit message.
    • Edit these as needed via the GitHub web interface (not via Gerrit or git).
    • You should word wrap the PR description at ~76 characters unless you need longer lines (e.g., for tables or URLs).
  • See the Sending a change via GitHub and Reviews sections of the Contribution Guide as well as the FAQ for details.

@gopherbot
Copy link
Contributor

Message from Gopher Robot:

Patch Set 1:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/751400.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Contributor

Message from Gopher Robot:

Patch Set 1:

Congratulations on opening your first change. Thank you for your contribution!

Next steps:
A maintainer will review your change and provide feedback. See
https://go.dev/doc/contribute#review for more info and tips to get your
patch through code review.

Most changes in the Go project go through a few rounds of revision. This can be
surprising to people new to the project. The careful, iterative review process
is our way of helping mentor contributors and ensuring that their contributions
have a lasting impact.


Please don’t reply on this GitHub thread. Visit golang.org/cl/751400.
After addressing review feedback, remember to publish your drafts!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants