Lsp-mode: Symbol鈥檚 value as variable is void: capability

Created on 8 Dec 2018  路  9Comments  路  Source: emacs-lsp/lsp-mode

When I open a file test.sh consisting of

echo hello

and run M-x lsp, I get a message Initialized server v. 1.5.5 for file:///...; but when for example I hover on an identifier, I get a message like

Error running timer: (void-variable capability)

instead of the intended information. If I run M-x lsp-describe-thing-at-point, I get the message Symbol鈥檚 value as variable is void: capability.

Ditto in a file test.py consisting of

print(hello)

so this seems not to be language-specific.

I just updated all packages today; I have lsp-mode-20181206.2007, lsp-ui-20181205.2047, and dash-20180910.1856, on Emacs 25.1.

See also #480 which is affecting me and may be related.

I enabled error-on-debug, and haven't gotten tracebacks from this. But here's a paste from my *Messages*, thanks to lsp-print-io:

>>> pyls:22583 status:starting(async)
Content-Length: 1440

{
  "jsonrpc": "2.0",
  "method": "initialize",
  "params": {
    "processId": 21107,
    "rootPath": "/home/greg/tmp/",
    "rootUri": "file:///home/greg/tmp/",
    "capabilities": {
      "workspace": {
        "applyEdit": true,
        "executeCommand": {
          "dynamicRegistration": false
        },
        "workspaceFolders": true
      },
      "textDocument": {
        "synchronization": {
          "willSave": true,
          "didSave": true,
          "willSaveWaitUntil": true
        },
        "documentSymbol": {
          "symbolKind": {
            "valueSet": [
              1,
              2,
              3,
              4,
              5,
              6,
              7,
              8,
              9,
              10,
              11,
              12,
              13,
              14,
              15,
              16,
              17,
              18,
              19,
              20,
              21,
              22,
              23,
              24,
              25
            ]
          },
          "hierarchicalDocumentSymbolSupport": true
        },
        "formatting": {
          "dynamicRegistration": true
        },
        "codeAction": {
          "dynamicRegistration": true
        },
        "completion": {
          "completionItem": {
            "snippetSupport": true
          }
        }
      }
    },
    "initializationOptions": null
  },
  "id": 11
}
<<<< pyls:22583 status:starting
{
  "result": {
    "capabilities": {
      "signatureHelpProvider": {
        "triggerCharacters": [
          "(",
          ","
        ]
      },
      "completionProvider": {
        "resolveProvider": false,
        "triggerCharacters": [
          "."
        ]
      },
      "documentFormattingProvider": true,
      "hoverProvider": true,
      "documentHighlightProvider": true,
      "textDocumentSync": 2,
      "documentRangeFormattingProvider": true,
      "renameProvider": true,
      "experimental": null,
      "documentSymbolProvider": true,
      "definitionProvider": true,
      "executeCommandProvider": {
        "commands": []
      },
      "codeActionProvider": true,
      "referencesProvider": true,
      "codeLensProvider": {
        "resolveProvider": false
      }
    }
  },
  "jsonrpc": "2.0",
  "id": 11
}
>>> pyls:22583(async)
Content-Length: 68

{
  "jsonrpc": "2.0",
  "method": "initialized",
  "params": {
  }
}
>>> pyls:22583(async)
Content-Length: 234

{
  "jsonrpc": "2.0",
  "method": "textDocument/didOpen",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py",
      "languageId": "python",
      "version": 0,
      "text": "print('hello')\n"
    }
  }
}
<<<< pyls:22583
{
  "jsonrpc": "2.0",
  "method": "textDocument/publishDiagnostics",
  "params": {
    "uri": "file:///home/greg/tmp/test.py",
    "diagnostics": []
  }
}
>>> pyls:22583(async)
Content-Length: 368

{
  "jsonrpc": "2.0",
  "method": "textDocument/codeAction",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "range": {
      "start": {
        "line": 1,
        "character": 0
      },
      "end": {
        "line": 1,
        "character": 0
      }
    },
    "context": {
      "diagnostics": []
    }
  },
  "id": 12
}
<<<< pyls:22583
{
  "result": [],
  "jsonrpc": "2.0",
  "id": 12
}
>>> pyls:22583(async)
Content-Length: 369

{
  "jsonrpc": "2.0",
  "method": "textDocument/codeAction",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "range": {
      "start": {
        "line": 0,
        "character": 0
      },
      "end": {
        "line": 0,
        "character": 14
      }
    },
    "context": {
      "diagnostics": []
    }
  },
  "id": 13
}
Error running timer: (void-variable capability)
<<<< pyls:22583
{
  "result": [],
  "jsonrpc": "2.0",
  "id": 13
}
>>> pyls:22583(async)
Content-Length: 235

{
  "jsonrpc": "2.0",
  "method": "textDocument/documentHighlight",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "position": {
      "line": 0,
      "character": 0
    }
  },
  "id": 14
}
eldoc error: (void-variable capability)
<<<< pyls:22583
{
  "result": [
    {
      "range": {
        "end": {
          "line": 0,
          "character": 5
        },
        "start": {
          "line": 0,
          "character": 0
        }
      },
      "kind": 2
    }
  ],
  "jsonrpc": "2.0",
  "id": 14
}
>>> pyls:22583(async)
Content-Length: 369

{
  "jsonrpc": "2.0",
  "method": "textDocument/codeAction",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "range": {
      "start": {
        "line": 0,
        "character": 0
      },
      "end": {
        "line": 0,
        "character": 14
      }
    },
    "context": {
      "diagnostics": []
    }
  },
  "id": 15
}
Error running timer: (void-variable capability)
<<<< pyls:22583
{
  "result": [],
  "jsonrpc": "2.0",
  "id": 15
}
>>> pyls:22583(async)
Content-Length: 235

{
  "jsonrpc": "2.0",
  "method": "textDocument/documentHighlight",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "position": {
      "line": 0,
      "character": 1
    }
  },
  "id": 16
}
eldoc error: (void-variable capability)
<<<< pyls:22583
{
  "result": [
    {
      "range": {
        "end": {
          "line": 0,
          "character": 5
        },
        "start": {
          "line": 0,
          "character": 0
        }
      },
      "kind": 2
    }
  ],
  "jsonrpc": "2.0",
  "id": 16
}
>>> pyls:22583(async)
Content-Length: 368

{
  "jsonrpc": "2.0",
  "method": "textDocument/codeAction",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "range": {
      "start": {
        "line": 1,
        "character": 0
      },
      "end": {
        "line": 1,
        "character": 0
      }
    },
    "context": {
      "diagnostics": []
    }
  },
  "id": 17
}
<<<< pyls:22583
{
  "result": [],
  "jsonrpc": "2.0",
  "id": 17
}
scroll-up-command: End of buffer [13 times]
Mark set [2 times]
Quit [2 times]
<C-mouse-1> is undefined
>>> pyls:22583(async)
Content-Length: 368

{
  "jsonrpc": "2.0",
  "method": "textDocument/codeAction",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "range": {
      "start": {
        "line": 1,
        "character": 0
      },
      "end": {
        "line": 1,
        "character": 0
      }
    },
    "context": {
      "diagnostics": []
    }
  },
  "id": 18
}
<<<< pyls:22583
{
  "result": [],
  "jsonrpc": "2.0",
  "id": 18
}
>>> pyls:22583(async)
Content-Length: 369

{
  "jsonrpc": "2.0",
  "method": "textDocument/codeAction",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "range": {
      "start": {
        "line": 0,
        "character": 0
      },
      "end": {
        "line": 0,
        "character": 14
      }
    },
    "context": {
      "diagnostics": []
    }
  },
  "id": 19
}
Error running timer: (void-variable capability)
<<<< pyls:22583
{
  "result": [],
  "jsonrpc": "2.0",
  "id": 19
}
or: Symbol鈥檚 value as variable is void: capability
>>> pyls:22583(async)
Content-Length: 368

{
  "jsonrpc": "2.0",
  "method": "textDocument/codeAction",
  "params": {
    "textDocument": {
      "uri": "file:///home/greg/tmp/test.py"
    },
    "range": {
      "start": {
        "line": 1,
        "character": 0
      },
      "end": {
        "line": 1,
        "character": 0
      }
    },
    "context": {
      "diagnostics": []
    }
  },
  "id": 20
}
<<<< pyls:22583
{
  "result": [],
  "jsonrpc": "2.0",
  "id": 20
}

Most helpful comment

Your code behaves just like it is compiled against some old version of dash which does not allow (&plist :capability :registered-capability) syntax . Did you try find ~/.emacs.d -name "*.elc" | xargs rm?

All 9 comments

I have commented in #480 . Can you try to reinstall lsp-mode. Alternatively you may delete the elc files in emacs.d - find ~/.emacs.d -name "*.elc" | xargs rm

After reinstalling lsp-mode and in a freshly started Emacs, the issue still reproduces... but this time with a debugger trace!

Debugger entered--Lisp error: (void-variable capability)
  (if capability (progn (lsp--capability capability)))
  (or (if capability (progn (lsp--capability capability))) (if registered-capability (progn (lsp--registered-capability registered-capability))) (and (not capability) (not registered-capability)))
  (let ((lsp--cur-workspace it)) (or (if capability (progn (lsp--capability capability))) (if registered-capability (progn (lsp--registered-capability registered-capability))) (and (not capability) (not registered-capability))))
  (if (let ((lsp--cur-workspace it)) (or (if capability (progn (lsp--capability capability))) (if registered-capability (progn (lsp--registered-capability registered-capability))) (and (not capability) (not registered-capability)))) (progn (setq result (cons it result))))
  (let ((it (car list))) (if (let ((lsp--cur-workspace it)) (or (if capability (progn (lsp--capability capability))) (if registered-capability (progn (lsp--registered-capability registered-capability))) (and (not capability) (not registered-capability)))) (progn (setq result (cons it result)))))
  (while list (let ((it (car list))) (if (let ((lsp--cur-workspace it)) (or (if capability (progn (lsp--capability capability))) (if registered-capability (progn (lsp--registered-capability registered-capability))) (and (not capability) (not registered-capability)))) (progn (setq result (cons it result))))) (setq it-index (1+ it-index)) (setq list (cdr list)))
  (let ((list (lsp-workspaces)) (it-index 0)) (while list (let ((it (car list))) (if (let ((lsp--cur-workspace it)) (or (if capability (progn ...)) (if registered-capability (progn ...)) (and (not capability) (not registered-capability)))) (progn (setq result (cons it result))))) (setq it-index (1+ it-index)) (setq list (cdr list))))
  (let (result) (let ((list (lsp-workspaces)) (it-index 0)) (while list (let ((it (car list))) (if (let ((lsp--cur-workspace it)) (or (if capability ...) (if registered-capability ...) (and ... ...))) (progn (setq result (cons it result))))) (setq it-index (1+ it-index)) (setq list (cdr list)))) (nreverse result))
  (if :registered-capability (let (result) (let ((list (lsp-workspaces)) (it-index 0)) (while list (let ((it (car list))) (if (let (...) (or ... ... ...)) (progn (setq result ...)))) (setq it-index (1+ it-index)) (setq list (cdr list)))) (nreverse result)) (lsp-workspaces))
  (let ((:registered-capability (plist-get (cdr (assoc (plist-get msg :method) lsp-method-requirements)) :capability))) (if :registered-capability (let (result) (let ((list (lsp-workspaces)) (it-index 0)) (while list (let ((it ...)) (if (let ... ...) (progn ...))) (setq it-index (1+ it-index)) (setq list (cdr list)))) (nreverse result)) (lsp-workspaces)))
  lsp--find-workspaces-for((:jsonrpc "2.0" :method "textDocument/hover" :params (:textDocument (:uri "file:///home/greg/tmp/test.py") :position (:line 0 :character 0))))
  (and t (lsp--find-workspaces-for body))
  (let* ((target-workspaces (and t (lsp--find-workspaces-for body)))) (if target-workspaces (let* ((async-callback (lsp--create-async-callback-wrapper (length target-workspaces) callback mode (plist-get body :method))) (id (setq lsp-last-id (1+ lsp-last-id))) (body (plist-put body :id id))) (let ((list target-workspaces) (it-index 0)) (while list (let ((it ...)) (let (...) (let ... ... ...))) (setq it-index (1+ it-index)) (setq list (cdr list)))) body) (error "No workspace could handle %s" (plist-get body :method))))
  lsp--send-request-async((:jsonrpc "2.0" :method "textDocument/hover" :params (:textDocument (:uri "file:///home/greg/tmp/test.py") :position (:line 0 :character 0))) #[257 "\211\205\n\303\300\301\302$\207" ["print" 1 (1 . 6) lsp-ui-sideline--push-info] 6 "\n\n(fn INFO)"])
  lsp-ui-sideline--run()
  #[0 "\300p\232\205\301 \207" [#<buffer test.py> lsp-ui-sideline--run] 2]()
  apply(#[0 "\300p\232\205\301 \207" [#<buffer test.py> lsp-ui-sideline--run] 2] nil)
  timer-event-handler([t 0 0 200000 nil #[0 "\300p\232\205\301 \207" [#<buffer test.py> lsp-ui-sideline--run] 2] nil idle 0])

So that seems potentially informative.

Looks like that's in the middle of this function:

(defun lsp--find-workspaces-for (msg)
  "Find all workspaces in the current that can handle MSG."
  ;; (setq my/msg msg)
  (-if-let ((&plist :capability :registered-capability)
            (cdr (assoc (plist-get msg :method) lsp-method-requirements)))
      (--filter
       (with-lsp-workspace it
         (or (when capability (lsp--capability capability))
             (when registered-capability
               (lsp--registered-capability registered-capability))
             (and (not capability) (not registered-capability))))
       (lsp-workspaces))
    (lsp-workspaces)))

(just from looking for references to lsp--capability that seem like a possible match)

Again there's clearly some magic going on with dash which I haven't read up on, and so I'm not sure how to interpret this or what the bug is.

Your code behaves just like it is compiled against some old version of dash which does not allow (&plist :capability :registered-capability) syntax . Did you try find ~/.emacs.d -name "*.elc" | xargs rm?

Also, can you check whether you have only one version of dash installed by doing calling find-library?

Hmm. I actually after first getting this error, and before reporting it, had blown away my whole ~/.emacs.d/elpa/ and reinstalled everything there. So there shouldn't be anywhere for an old dash to linger.

I ran M-x find-library dash, and it sent me to ~/.emacs.d/elpa/dash-20180910.1856/dash.el.

I pinged you on gitter.

The issue is fixed. Somehow @gnprice had previous version of dash loaded. Once we ensured that the new version of dash was loaded the issue disappeared.

Thanks @yyoncho for the help debugging!

We still don't understand quite how I got into this state (at least after the reinstall I mentioned above), but these steps diagnosed it and fixed it:

  • This fragment of dash-using code gave an error, if evaluated (with C-x C-e in *scratch*):
    (-let (((&plist :capability :registered-capability) (list :capability 10 :registered-capability 10))) (list capability registered-capability))
  • Then I ran M-x eval-buffer in dash.el -- and then evaluating that same fragment gave no error
  • Then I ran M-x eval-buffer in lsp.el -- and then lsp-mode worked!
  • Also M-x byte-compile-file on lsp.el now worked with no error, i.e., #480 was resolved
  • I went back and ran M-x byte-compile-file on dash.el, and then in a fresh Emacs everything worked.
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bradprob picture bradprob  路  5Comments

alanz picture alanz  路  6Comments

axelson picture axelson  路  4Comments

mcraveiro picture mcraveiro  路  3Comments

dchneric picture dchneric  路  3Comments