emacs-lsp / lsp-mode

Emacs client/library for the Language Server Protocol
https://emacs-lsp.github.io/lsp-mode
GNU General Public License v3.0
4.81k stars 890 forks source link

`lsp-install-server` fails with `Invalid command list` assertion #4099

Open Hi-Angel opened 1 year ago

Hi-Angel commented 1 year ago

Thank you for the bug report

Bug description

Just tried lsp-install-server and found out by default it fails with There is no automatic installation for ‘nil’, and with lsp-start-plain which presumably does some additional checks it fails with the assert.

I did some debugging — my PR was recently merged so I was afraid I might have something broke. I found that the assertion inside lsp-resolve-final-function happens because some server is declared as (nil "--stdio=true"). There is only one server that has "--stdio=true", it is credo-language-server (which I didn't touch).

I looked through the code of credo-language-server, but haven't found anything suspicious. I don't know details of the initialization, so at this point I decided to report the bug.

Steps to reproduce

  1. Execute M-x lsp-start-plain
  2. Execute M-x lsp-install-server

Expected behavior

A prompt asking what server you want to install would appear

Which Language Server did you use?

None

OS

Linux

Error callstack

Details using lsp-start-plain

Stacktrace ```emacs-lisp Debugger entered--Lisp error: (cl-assertion-failed ((seq-every-p (apply-partially #'stringp) command) "Invalid command list")) cl--assertion-failed((seq-every-p (apply-partially #'stringp) command) "Invalid command list" nil nil) (or (seq-every-p (apply-partially #'stringp) command) (cl--assertion-failed '(seq-every-p (apply-partially #'stringp) command) "Invalid command list" (list) (list))) (progn (or (seq-every-p (apply-partially #'stringp) command) (cl--assertion-failed '(seq-every-p (apply-partially #'stringp) command) "Invalid command list" (list) (list))) nil) (cond ((listp command) (progn (or (seq-every-p (apply-partially #'stringp) command) (cl--assertion-failed '(seq-every-p (apply-partially ...) command) "Invalid command list" (list) (list))) nil) command) ((stringp command) (list command)) ((error "cl-etypecase failed: %s, %s" command '(list string)) nil)) (let* ((command (if (functionp command) (funcall command) command))) (cond ((listp command) (progn (or (seq-every-p (apply-partially #'stringp) command) (cl--assertion-failed '(seq-every-p ... command) "Invalid command list" (list) (list))) nil) command) ((stringp command) (list command)) ((error "cl-etypecase failed: %s, %s" command '(list string)) nil))) lsp-resolve-final-function((closure (t) nil (cons (or (executable-find (cl-first lsp-credo-command)) (lsp-package-path 'credo-language-server)) (cl-rest lsp-credo-command)))) (lsp-server-present? (lsp-resolve-final-function command)) (closure ((command closure (t) nil (cons (or (executable-find (cl-first lsp-credo-command)) (lsp-package-path 'credo-language-server)) (cl-rest lsp-credo-command)))) nil (lsp-server-present? (lsp-resolve-final-function command)))() funcall((closure ((command closure (t) nil (cons (or (executable-find (cl-first lsp-credo-command)) (lsp-package-path 'credo-language-server)) (cl-rest lsp-credo-command)))) nil (lsp-server-present? (lsp-resolve-final-function command)))) (progn (funcall result)) (if result (progn (funcall result))) (let ((result (let ((result (let (...) (if result ...)))) (if result (progn (plist-get result :test?)))))) (if result (progn (funcall result)))) (condition-case nil (let ((result (let ((result (let ... ...))) (if result (progn (plist-get result :test?)))))) (if result (progn (funcall result)))) (error nil) (args-out-of-range nil)) (if (equal (let* ((cl-x client)) (progn (or (let* ((cl-x cl-x)) (progn (and ... t))) (signal 'wrong-type-argument (list 'lsp--client cl-x))) (aref cl-x 15))) 'lsp-pwsh) nil (condition-case nil (let ((result (let ((result ...)) (if result (progn ...))))) (if result (progn (funcall result)))) (error nil) (args-out-of-range nil))) lsp--server-binary-present?(#s(lsp--client :language-id nil :add-on? t :new-connection (:connect (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) (filter sentinel name environment-fn workspace) (if (functionp 'json-rpc-connection) (lsp-json-rpc-connection workspace (lsp-resolve-final-function command)) (let ((final-command ...) (process-name ...) (process-environment ...)) (let* (... ... ...) (set-process-query-on-exit-flag proc nil) (set-process-query-on-exit-flag ... nil) (save-current-buffer ... ...) (cons proc proc))))) :test? (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) nil (lsp-server-present? (lsp-resolve-final-function command)))) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes nil :activation-fn (closure ((languages "elixir")) (_file-name _mode) (-contains? languages (lsp-buffer-language))) :priority -1 :server-id credo-language-server :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn (closure (t) (_client callback error-callback _update?) (lsp-package-ensure 'credo-language-server callback error-callback)) :download-in-progress? nil :buffers nil :synchronize-sections nil)) (if (lsp--server-binary-present? client) (concat server-name " (Already installed)") server-name) (let ((server-name (symbol-name (let* ((cl-x client)) (progn (or (let* ... ...) (signal ... ...)) (aref cl-x 15)))))) (if (lsp--server-binary-present? client) (concat server-name " (Already installed)") server-name)) (closure (t) (client) (let ((server-name (symbol-name (let* (...) (progn ... ...))))) (if (lsp--server-binary-present? client) (concat server-name " (Already installed)") server-name)))(#s(lsp--client :language-id nil :add-on? t :new-connection (:connect (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) (filter sentinel name environment-fn workspace) (if (functionp 'json-rpc-connection) (lsp-json-rpc-connection workspace (lsp-resolve-final-function command)) (let ((final-command ...) (process-name ...) (process-environment ...)) (let* (... ... ...) (set-process-query-on-exit-flag proc nil) (set-process-query-on-exit-flag ... nil) (save-current-buffer ... ...) (cons proc proc))))) :test? (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) nil (lsp-server-present? (lsp-resolve-final-function command)))) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes nil :activation-fn (closure ((languages "elixir")) (_file-name _mode) (-contains? languages (lsp-buffer-language))) :priority -1 :server-id credo-language-server :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn (closure (t) (_client callback error-callback _update?) (lsp-package-ensure 'credo-language-server callback error-callback)) :download-in-progress? nil :buffers nil :synchronize-sections nil)) funcall((closure (t) (client) (let ((server-name (symbol-name (let* (...) (progn ... ...))))) (if (lsp--server-binary-present? client) (concat server-name " (Already installed)") server-name))) #s(lsp--client :language-id nil :add-on? t :new-connection (:connect (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) (filter sentinel name environment-fn workspace) (if (functionp 'json-rpc-connection) (lsp-json-rpc-connection workspace (lsp-resolve-final-function command)) (let ((final-command ...) (process-name ...) (process-environment ...)) (let* (... ... ...) (set-process-query-on-exit-flag proc nil) (set-process-query-on-exit-flag ... nil) (save-current-buffer ... ...) (cons proc proc))))) :test? (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) nil (lsp-server-present? (lsp-resolve-final-function command)))) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes nil :activation-fn (closure ((languages "elixir")) (_file-name _mode) (-contains? languages (lsp-buffer-language))) :priority -1 :server-id credo-language-server :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn (closure (t) (_client callback error-callback _update?) (lsp-package-ensure 'credo-language-server callback error-callback)) :download-in-progress? nil :buffers nil :synchronize-sections nil)) (cons (funcall transform-fn it) it) (closure ((transform-fn closure (t) (client) (let ((server-name (symbol-name ...))) (if (lsp--server-binary-present? client) (concat server-name " (Already installed)") server-name)))) (it) (ignore it) (cons (funcall transform-fn it) it))(#s(lsp--client :language-id nil :add-on? t :new-connection (:connect (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) (filter sentinel name environment-fn workspace) (if (functionp 'json-rpc-connection) (lsp-json-rpc-connection workspace (lsp-resolve-final-function command)) (let ((final-command ...) (process-name ...) (process-environment ...)) (let* (... ... ...) (set-process-query-on-exit-flag proc nil) (set-process-query-on-exit-flag ... nil) (save-current-buffer ... ...) (cons proc proc))))) :test? (closure ((command closure (t) nil (cons (or ... ...) (cl-rest lsp-credo-command)))) nil (lsp-server-present? (lsp-resolve-final-function command)))) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes nil :activation-fn (closure ((languages "elixir")) (_file-name _mode) (-contains? languages (lsp-buffer-language))) :priority -1 :server-id credo-language-server :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn (closure (t) (_client callback error-callback _update?) (lsp-package-ensure 'credo-language-server callback error-callback)) :download-in-progress? nil :buffers nil :synchronize-sections nil)) mapcar((closure ... ... ... ...) (... ... ... ... ... ... ... ... ... ... ... ... ... ... ...)) (let* ((col (mapcar #'(lambda (it) (ignore it) (cons (funcall transform-fn it) it)) collection)) (completion (completing-read prompt #'(lambda (string pred action) (if (eq action ...) '... (complete-with-action action col string pred))) predicate require-match initial-input hist def inherit-input-method))) (cdr (assoc completion col))) lsp--completing-read("Select server ..." (... ... ... ... ... ... ... ... ... ... ... ... ... ... ...) (closure ... ... ...) nil t) (or (gethash server-id lsp-clients) (lsp--completing-read "Select server to install/re-install: " (or (-filter (-andfn (-not #'lsp--client-download-in-progress?) #'lsp--client-download-server-fn) (ht-values lsp-clients)) (user-error "There are no servers with automatic installation")) #'(lambda (client) (let ((server-name (symbol-name ...))) (if (lsp--server-binary-present? client) (concat server-name " (Already installed)") server-name))) nil t)) (let* ((chosen-client (or (gethash server-id lsp-clients) (lsp--completing-read "Select server to install/re-install: " (or (-filter (-andfn ... ...) (ht-values lsp-clients)) (user-error "There are no servers with automatic installation")) #'(lambda (client) (let ... ...)) nil t))) (update? (or update? (and (not (let* (...) (progn ... ...))) (lsp--server-binary-present? chosen-client))))) (lsp--install-server-internal chosen-client update?)) lsp-install-server(nil) funcall-interactively(lsp-install-server nil) command-execute(lsp-install-server record) execute-extended-command(nil "lsp-install-server" nil) funcall-interactively(execute-extended-command nil "lsp-install-server" nil) command-execute(execute-extended-command) ```
*lsp-log* ``` Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. Command "semgrep lsp" is not present on the path. Command "clangd --header-insertion-decorators=0" is present on the path. Command "semgrep lsp" is not present on the path. Command "clangd --header-insertion-decorators=0" is present on the path. Found the following clients for /home/constantine/Projects/builds/emacs-git/src/emacs-git/src/eval.c: (server-id clangd, priority -1) The following clients were selected based on priority: (server-id clangd, priority -1) Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. Command "/usr/lib/rustup/bin/rust-analyzer" is present on the path. Command "perlnavigator --stdio" is not present on the path. Command "java -jar /home/constantine/.emacs.d/.cache/lsp/magik-ls/magik-language-server-0.7.1.jar --debug" is not present on the path. Command "marksman" is not present on the path. Command "kotlin-language-server" is not present on the path. ```

lsp-workspace-show-log asks for a workspace and I don't have anything to type.

Anything else?

No response

jcs090218 commented 8 months ago

Do you know which servers have (nil "--stdio=true")? 🤔

Hi-Angel commented 8 months ago

Do you know which servers have (nil "--stdio=true")? 🤔

I presume you're asking which one has nil (because which servers has --stdio=true I mentioned). Well, that I don't know. The only one with --stdio=true has no nil. No idea where did it come from.