typescript-language-server / typescript-language-server

TypeScript & JavaScript Language Server

Home Page:https://www.npmjs.com/package/typescript-language-server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Server crashed when asking for textDocument/codeAction

minikN opened this issue · comments

Hello,

I'm using typescript-language-server version 4.1.2 (but I also tried this with 4.2.0) and I'm running into the following error when a textDocument/codeAction request:

jsonrpc-request: jsonrpc-error: "request id=14 failed:", (jsonrpc-error-code . 1), (jsonrpc-error-message . "<semantic> TypeScript Server Error (5.3.3)
BADCLIENT: Bad error code, 7044 not found in range 592..592 (found: false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); could have caused this error:
Debug Failure. Invalid cast. The supplied value [object Object] did not pass the test 'isCallExpression'.
Error: BADCLIENT: Bad error code, 7044 not found in range 592..592 (found: false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); could have caused this error:
Debug Failure. Invalid cast. The supplied value [object Object] did not pass the test 'isCallExpression'.
    at cast (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:3481:16)
    at addMissingNewOperator (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:152939:16)
    at /home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:152932:79
    at _ChangeTracker.with (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:168580:5)
    at Object.getCodeActions (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:152932:62)
    at /home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:147100:46
    at flatMap (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:2597:17)
    at Object.getFixes (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:147100:10)
    at /home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:145385:33
    at flatMap (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:2597:17)
    at Object.getCodeFixesAtPosition (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:145383:12)
    at IpcIOSession.getCodeFixes (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:185071:50)
    at getCodeFixes (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:183183:43)
    at /home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:185375:69
    at IpcIOSession.executeWithRequestId (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:185367:14)
    at IpcIOSession.executeCommand (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:185375:29)
    at IpcIOSession.onMessage (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:185417:51)
    at process.<anonymous> (/home/db/.npm-global/lib/node_modules/typescript/lib/tsserver.js:186999:14)
    at process.emit (node:events:514:28)
    at emit (node:internal/child_process:951:14)
    at process.processTicksAndRejections (node:internal/process/task_queues:83:21)"), (jsonrpc-error-data)

I'm using the server on NixOS in Emacs, using the Eglot package. I also reported this error to eglot here. But they suggested this is an error with typescript-language-server or even typescript itself.

Full log of client/server interaction: https://pastebin.com/kwVWdTuf

Using:

  • typescript-language-server 4.1.2 (but also tested with 4.2.0)
  • typescript 5.3.3 (bundled)
  • node v.18.19.0

I can't share the JSX file I created this error with publicly, but I can send it to someone via email in an effort to help debugging this.

Thanks.

This looks like a typescript problem and ideally we'd have a reproduction and report it there. If you have vscode then you could try the same file there to verify that.

This looks like a typescript problem and ideally we'd have a reproduction and report it there. If you have vscode then you could try the same file there to verify that.

Hello,

I opened the same JSX file in vscode 1.85.1, and did S-C-p -> Source Action. It did not break. But my understanding is that VSCode doesn't use typescript-language-server, but rather taps into tsserver directly. Am I wrong? I searched through the tsserver log, but I couldn't find textDocument/codeAction there (it's over 60k lines long, can't even upload it).

VSCode seems to be using typescript 5.3.2 while emacs/eglot are using 5.3.3. Don't know if that makes any difference.

VSCode:

Version: 1.85.1
Commit: 0ee08df0cf4527e40edc9aa28f4b5bd38bbff2b2
Date: 2023-12-13T09:47:11.635Z
Electron: 25.9.7
ElectronBuildId: 25551756
Chromium: 114.0.5735.289
Node.js: 18.15.0
V8: 11.4.183.29-electron.0
OS: Linux x64 6.6.8

VSCode doesn't use this server but the underlaying code is very similar since this server is based on vscode's code, with LSP layer added. So usually low-level issues like that reproduce the same.

You can make VSCode use different version of typescript by clicking on its status field. You would ideally install 5.3.3 in your project and then switch it to use project version.

And note that you've shared the source code of that file in the log since LSP logs include it when opening the file. So if you don't want to share it, you might want to remove that pastebin. I've downloaded it locally already so I can try to see if I can reproduce with just that file when I have some time.

I'm missing your dependencies and other project configuration but with that file the InlayHints request fails with:

{
    "code": 1,
    "message": "<semantic> TypeScript Server Error (5.3.3)\nDebug Failure. Unexpected node.\r\nNode ObjectBindingPattern was unexpected.\nError: Debug Failure. Unexpected node.\r\nNode ObjectBindingPattern was unexpected.\n    at visitForDisplayParts (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:165383:17)\n    at visitForDisplayParts (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:165188:11)\n    at /usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:165391:9\n    at Array.forEach (<anonymous>)\n    at visitDisplayPartList (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:165387:13)\n    at visitForDisplayParts (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:165340:11)\n    at typeToInlayHintParts (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:165113:5)\n    at visitVariableLikeDeclaration (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:164921:23)\n    at visitor (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:164843:7)\n    at visitNodes (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30235:22)\n    at forEachChildInVariableDeclarationList (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30454:12)\n    at forEachChild (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30744:35)\n    at visitor (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:164858:12)\n    at visitNode2 (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30227:18)\n    at forEachChildInVariableStatement (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30451:59)\n    at forEachChild (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30744:35)\n    at visitor (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:164858:12)\n    at visitNodes (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30235:22)\n    at forEachChildInSourceFile (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30448:12)\n    at forEachChild (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:30744:35)\n    at visitor (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:164858:12)\n    at Object.provideInlayHints (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:164819:3)\n    at Object.provideInlayHints2 [as provideInlayHints] (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:145844:34)\n    at IpcIOSession.provideInlayHints (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:184197:48)\n    at provideInlayHints (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:183356:43)\n    at /usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:185375:69\n    at IpcIOSession.executeWithRequestId (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:185367:14)\n    at IpcIOSession.executeCommand (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:185375:29)\n    at IpcIOSession.onMessage (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:185417:51)\n    at process.<anonymous> (/usr/local/workspace/github/typescript-language-server/node_modules/typescript/lib/tsserver.js:186999:14)\n    at process.emit (node:events:514:28)\n    at emit (node:internal/child_process:937:14)\n    at process.processTicksAndRejections (node:internal/process/task_queues:83:21)"
}

Not sure how related it is but it's still something for typescript to handle.

And note that you've shared the source code of that file in the log since LSP logs include it when opening the file. So if you don't want to share it, you might want to remove that pastebin. I've downloaded it locally already so I can try to see if I can reproduce with just that file when I have some time.

Yeah, I noticed that too. Anyway it already happened 😝

And note that you've shared the source code of that file in the log since LSP logs include it when opening the file. So if you don't want to share it, you might want to remove that pastebin. I've downloaded it locally already so I can try to see if I can reproduce with just that file when I have some time.

I added typescript version 5.3.3 to VSCode, but that didn't change, it still works. But I don't know how reliable that is, because VSCode sends

    {
      "seq": 19,
      "type": "request",
      "command": "getApplicableRefactors",
      "arguments": {
        "file": "/home/db/.local/share/git/gaia/client/platform/web/src/ui/Component/File/Hotspot.jsx",
        "startLine": 14,
        "startOffset": 27,
        "endLine": 14,
        "endOffset": 27,
        "triggerReason": "implicit",
        "includeInteractiveActions": true
      }
    }

which is not the same request I send from eglot.

Any other ideas on how to reproduce this?

Note that the jsx files should use javascriptreact language ID in didOpen notification. Typescript has JSX (and TSX) specific logic in some cases so it needs to know the correct language ID for proper functioning.

I have reproduced your error by hardcoding the parameters in the textDocument/codeAction request to the same ones that your editor sends.

I believe the reason for that error might be that your editor doesn't quite follow the expected LSP behavior (which I'm not sure if is very precisely specified).

Your editor is sending all file diagnostics in the params.context.diagnostics property:

{
    "jsonrpc": "2.0",
    "id": 6,
    "method": "textDocument/codeAction",
    "params": {
        "textDocument": {
            "uri": "file:///home/db/.local/share/git/gaia/client/platform/web/src/ui/Component/File/Hotspot.jsx"
        },
        "range": {
            "start": {
                "line": 0,
                "character": 0
            },
            "end": {
                "line": 0,
                "character": 0
            }
        },
        "context": {
            "diagnostics": <INCLUDES ALL DIAGNOSTICS HERE>
        }
    }
}

while the expected behavior is that the editor only includes diagnostics that overlap the params.range range.

The typescript error Bad error code, 7044 not found in range 592..592 seems to imply that it didn't find the 7044 diagnostic (which is one of those provided in the request) in the current range.

So it looks like an LSP client bug.

That is actually precisely specified:

export interface [CodeActionContext](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#codeActionContext) {
	/**
	 * An array of diagnostics known on the client side overlapping the range
	 * provided to the `textDocument/codeAction` request. They are provided so
	 * that the server knows which errors are currently presented to the user
	 * for the given range. There is no guarantee that these accurately reflect
	 * the error state of the resource. The primary parameter
	 * to compute code actions is the provided range.
	 */
	diagnostics: [Diagnostic](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic)[];

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#codeActionContext

Thanks @rchl for the investigation. I fixed it on my clients side, this was a combination of many factors like a missing complete error reproduction recipe (which I've now described back in the original issue). In certain combinations (invoking certain code actions with the cursor over whitespace, the Eglot client does send too many diagnostics). The server doesn't always error though, and when it does, it's impossible to make out what that long message and JS backtrace means. So, many thanks for having done that crucial part. I think this can be closed.