Skip to content

Stale errors remain in the stats and buffers, even when there are no errors #5043

Description

@ranjeethmahankali

Thank you for the bug report

  • I am using the latest version of lsp-mode related packages.
  • I checked FAQ and Troubleshooting sections
  • You may also try reproduce the issue using clean environment using the following command: M-x lsp-start-plain

Bug description

Errors, linter warnings occur while I am typing code, when I typed something incomplete or incorrect. But once I fix them, they should go away. This used to work fine until recently. After a recent update however, even after I fix all the errors and warnings, the title bar at the top of the file still has a red underline, and when I open LSP Error List buffer, it shows me, for example 9 errors (number may vary) but the list itself is empty. The code compiles fine. It's just hanging on to the errors that once were.

Steps to reproduce

Reproduction:**

  1. Open a file with LSP (needs a workflow that triggers lsp-after-apply-edits-hook, e.g. lsp-format-buffer on save)
  2. Introduce errors, then fix them and save
  3. Headerline breadcrumb still shows error face on the filename
  4. *LSP Errors List* reports N errors but lists none
  5. Restarting LSP server does not fix it — only restarting Emacs does

Expected behavior

When I fix the errors, the red underlines and the error statistics should be cleared.

Which Language Server did you use?

C++, clangd

OS

Linux

Error callstack

Anything else?

The following is the analysis, fix suggestion and workaround that Claude Code gave me. I sort of understand what it is saying at a high level, and the workaround does seem to do the trick in my config, but it may be all BS. If it doesn't help, please ignore the stuff below:

Root cause:**

lsp-diagnostics--clear-after-edit does remhash on (lsp--workspace-diagnostics workspace) without calling lsp-diagnostics--convert-and-update-path-stats first. This means:

  • The global lsp-diagnostic-stats is never decremented for the removed diagnostics
  • When the server next publishes diagnostics, the delta calculation in lsp-diagnostics--convert-and-update-path-stats finds no old diagnostics to subtract (already removed), so the counts only grow
  • lsp-diagnostics--workspace-cleanup also can't fix it, since it iterates the workspace hash which no longer contains the removed entries
  • The counts accumulate with each edit cycle and persist until Emacs restarts

Suggested fix:

Call lsp-diagnostics--convert-and-update-path-stats with empty diagnostics before the remhash:

(defun lsp-diagnostics--clear-after-edit (&rest _)
  (when-let* ((file-path (buffer-file-name))
              (workspaces (lsp-workspaces)))
    (let ((path (lsp--fix-path-casing file-path)))
      (dolist (workspace workspaces)
        (lsp-diagnostics--convert-and-update-path-stats workspace path nil)
        (-let [diagnostics (lsp--workspace-diagnostics workspace)]
          (remhash path diagnostics))))
    (run-hooks 'lsp-diagnostics-updated-hook)))

Workaround:

(remove-hook 'lsp-after-apply-edits-hook #'lsp-diagnostics--clear-after-edit)

This reverts to the pre-#3888 behavior where stale diagnostics may briefly appear at wrong line numbers after workspace edits, but avoids the permanent ghost error accumulation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions