Skip to content

[Bug]: Patched tsserver crashes when using client watch #6270

@clemyan

Description

@clemyan

Self-service

  • I'd be willing to implement a fix

Describe the bug

When using the client watch feature with the patched tsserver (introduced in TypeScript 5.3, commit, PR), the server crashes.

Looks like VS Code 1.89 (released 15 hours ago as of this writing) is A/B testing whether to use client watch in its TypeScript language service.

Investigation

In tsserver, client watch is enabled by the option canUseWatchEvents, which causes ProjectService to create different watch factories:
https://github.com/microsoft/TypeScript/blob/v5.5-beta/src/server/editorServices.ts#L1229

Then the patched tsserver (synchronously) calls watchPnpFile
https://github.com/yarnpkg/TypeScript/blob/merceyz/pnp-5.5-beta/src/server/editorServices.ts#L1238

When using client watch, that call ends up calling IOSession#event
https://github.com/microsoft/TypeScript/blob/v5.5-beta/src/tsserver/nodeServer.ts#L611-L612

which fails the first assert and crashes because the IOSession's constructor is still at the super call, before setting this.constructed to true.


To reproduce/investigate, make sure your VS Code is at version 1.89, enable client watch with "typescript.tsserver.experimental.useVsCodeWatcher": true, and enable logging with "typescript.tsserver.log": "verbose". By unplugging the typescript package we can insert log calls. Restart the TS server or extension host to trigger the error code path. The log file path can be found in the "Output" tab. (Note: there are 2 logs files, we want the semantic server log)

By printing the stacktrace and this.constructed at the start of IOSession#event we can verify the assert fails (line numbers may be slightly shifted due to added logs)

    at IpcIOSession.event ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\tsserver.js:502:25)
    at IpcIOSession.defaultEventHandler ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:189562:14)
    at _ProjectService.eventHandler ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:189465:83)
    at getOrCreateFileWatcher ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:184920:15)
    at Object.watchFile2 [as watchFile] ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:184888:12)
    at watchFile ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:123187:67)
    at Object.watchFile ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:123256:92)
    at createFileWatcherWithLogging ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:123229:44)
    at Object.watchFile ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:123206:283)
    at _ProjectService.watchPnpFile ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:188039:30)
    at new _ProjectService ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:185100:28)
    at new _Session ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\typescript.js:189494:27)
    at new IOSession ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\tsserver.js:476:7)
    at new IpcIOSession ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\tsserver.js:539:3)
    at startNodeSession ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\tsserver.js:576:34)
    at start ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\tsserver.js:636:3)
    at Object.<anonymous> ([PROJECT_ROOT]\.yarn\unplugged\typescript-patch-5205e392bf\node_modules\typescript\lib\tsserver.js:653:1)
    ---- snip ----

Indeed, we can verify that the server can run normally without crashing by either:

  • Disabling client watch in VS Code with "typescript.tsserver.experimental.useVsCodeWatcher": false
  • Delaying the said watchPnpFile call to the next tick via process.nextTick

To reproduce

  1. Install VS Code 1.89
  2. Open a TypeScript 5.5 project (if necessary, use a fresh --user-data-dir and/or disable extensions)
  3. Use TypeScript SDK
  4. Set config "typescript.tsserver.experimental.useVsCodeWatcher": true
  5. Open any TypeScript file and restart the extension host
  6. VS Code warns that "The JS/TS language service crashed."

Environment

System:
    OS: Windows 10 10.0.19045
    CPU: (16) x64 Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz      
  Binaries:
    Node: 20.8.1 - ~\AppData\Local\Temp\xfs-b99c0456\node.CMD   
    Yarn: 4.1.1-dev - ~\AppData\Local\Temp\xfs-b99c0456\yarn.CMD
    npm: 10.1.0 - C:\Program Files\nodejs\npm.CMD

Additional context

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions