lsp-mode icon indicating copy to clipboard operation
lsp-mode copied to clipboard

Issue when org mode errors

Open egh opened this issue 6 months ago • 4 comments

Thank you for the bug report

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

Bug description

When org-mode throws an error and is loaded before lsp-mode, it causes some issues (that I don't fully understand) with compilation that messes up the cl generic dispatch system. I've narrowed down this issue (after way too much work) to d1836275e85183cf381a36ab68248af6d9bff9ce. I have seen this issue on linux and mac os on Emacs 30.2. Breaking this means that lots of things start breaking in emacs.

Steps to reproduce

Here is a minimal file to reproduce (slightly updated from original report):

🤔 cat test.el
(setq package-archives
      '(("melpa" . "https://melpa.org/packages/")
        ("melpa-stable" . "https://stable.melpa.org/packages/")
        ("gnu-devel" . "https://elpa.gnu.org/packages/")))
(package-initialize)
(use-package org-mode :hook ((org-mode . foo)))
(ignore-errors
  (with-temp-buffer (org-mode)))
(use-package lsp-mode :ensure t)
(message "%s" (seq-empty-p '()))

🤔 emacs --batch --load test.el
Error (use-package): lsp-mode/:catch: Autoloading file /snap/emacs/current/usr/share/emacs/30.2/lisp/org/org.elc failed to define function foo

Error: cl-no-applicable-method (seq-empty-p nil)
  signal(cl-no-applicable-method (seq-empty-p nil))
  cl-no-applicable-method(#s(cl--generic :name seq-empty-p :dispatches nil :method-table nil :options nil) nil)
  apply(cl-no-applicable-method #s(cl--generic :name seq-empty-p :dispatches nil :method-table nil :options nil) nil)
  seq-empty-p(nil)
  (message "%s" (seq-empty-p 'nil))
  load-with-code-conversion("/home/egh/test.el" "/home/egh/test.el" nil t)
  command-line-1(("--load" "test.el"))
  command-line()
  normal-top-level()
No applicable method: seq-empty-p, nil

Expected behavior

This issue was introduced in d1836275e85183cf381a36ab68248af6d9bff9ce. Versions before that work fine.

🤔 rm -rf ~/.emacs.d/elpa

~ 
🤔 emacs --batch --load test.el
Importing package-keyring.gpg...
Importing package-keyring.gpg...done
Contacting host: melpa.org:443
Contacting host: melpa.org:443
...
t

Which Language Server did you use?

none, lsp mode itself only

OS

Linux

Error callstack


Anything else?

Wrapping the call to (org-mode) in lsp--org-element-use-new-api with (ignore-errors ...) corrects the issue.

egh avatar Oct 21 '25 21:10 egh

https://github.com/emacs-lsp/lsp-mode/commit/d1836275e85183cf381a36ab68248af6d9bff9ce (PR https://github.com/emacs-lsp/lsp-mode/pull/4889) also caused org-mode to break if one of the org-mode hooks throws an error (for example if buffer-file-name is nil). Here's a reproducer:

  (defun my-broken-hook ()
    (replace-regexp-in-string "/" "--" buffer-file-name))
  (add-hook 'org-mode-hook 'my-broken-hook)

In my case, wrapping (org-mode) in (ignore-errors) didn't help, Org still stays broken.

I'm confused by the decision to instantiate a full org-mode buffer just to perform a check for element API. Perhaps it would be simpler to use (org-version)?

My current workaround for this issue is to patch (lsp--detect-org-element-api) to always return t (because I know for sure that I'm on the newer versions, and also I don't use lsp-mode in Org buffers):

(defun lsp--detect-org-element-api () t)

Rogach avatar Oct 27 '25 20:10 Rogach

For anybody looking, this also creates the error:

cl-generic-ensure-function: lsp-execute-command is already defined as something else than a generic function

egh avatar Oct 27 '25 23:10 egh

This seems like a small issue, and in some ways it is, but if it is triggered it completely breaks fundamental parts of emacs. It's very hard to track what triggered the error.

I agree with @Rogach that it would probably be easy to check the org-version variable for api compatbility.

egh avatar Oct 27 '25 23:10 egh

My workaround wasn't enough - if org-mode is loaded before lsp-mode then my override runs when it's too late. Adding an advice around fixes it:

  (defun lsp--detect-org-element-api--always-true (orig-fun &rest args) t)
  (advice-add 'lsp--detect-org-element-api :around #'lsp--detect-org-element-api--always-true)

Rogach avatar Nov 03 '25 19:11 Rogach