Skip to content

Changing tsconfig.json results in Debug failures in tsserver #284

Open
@eXory2024

Description

@eXory2024

Describe the bug

While trying to implement my own LSP plugin (based on this one) I stumbled into the following bug:

Info 0    [11:51:44.517] Starting TS Server
Info 1    [11:51:44.518] Version: 5.8.3
Info 2    [11:51:44.518] Arguments: /usr/local/bin/node /Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/tsserver.js --useInferredProjectPerProjectRoot --cancellationPipeName /private/var/folders/fz/9n7tc0yn5td7jtkhzp1jg8cc0000gp/T/93085d9110aa8e8d610208cb1c34592b/tscancellation* --logVerbosity normal --logFile /tmp/tsc-logs/tsserver-log-AfW3kr/tsserver.log --locale en --validateDefaultNpmLocation --useNodeIpc
Info 3    [11:51:44.518] Platform: darwin NodeVersion: v23.11.0 CaseSensitive: false

[...]

    Debug Failure. False expression.

    Error: Debug Failure. False expression.
        at ConfiguredProject2.updateGraphWorker (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:186954:11)
        at ConfiguredProject2.updateGraph (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:186799:32)
        at ConfiguredProject2.updateGraph (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:188092:24)
        at updateWithTriggerFile (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:188636:11)
        at _ProjectService.reloadConfiguredProject (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:190340:5)
        at ConfiguredProject2.updateGraph (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:188088:29)
        at updateProjectIfDirty (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:188627:36)
        at /Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:189053:11
        at Timeout.run [as _onTimeout] (/Users/exory2024/Desktop/typescript-plugin-css-modules-bug/node_modules/typescript/lib/typescript.js:185111:5)
        at listOnTimeout (node:internal/timers:610:11)
        at process.processTimers (node:internal/timers:543:7)

At first I thought this error is coming from my plugin, but I found out that this is actually a bug in this project.

Looking at the stacktrace we can see the following assertion within typescript failed:

const oldProgram = this.languageService.getCurrentProgram();
Debug.assert(oldProgram === this.program);

Looking at the source of this plugin I'm pretty sure the error is produced by the following code that was added in the commit aa18204:

const languageServiceHost = {} as Partial<tsModule.LanguageServiceHost>

const languageServiceHostProxy = new Proxy(info.languageServiceHost, {
	get(target, key: keyof tsModule.LanguageServiceHost) {
		return languageServiceHost[key] ? languageServiceHost[key] : target[key]
	}
})

const languageService = ts.createLanguageService(languageServiceHostProxy)

return languageService

As far as I could find out, plugins shouldn't create a new language service object but extend the existing one like this:

// Set up decorator object
const proxy: ts.LanguageService = Object.create(null);

for (let k of Object.keys(info.languageService) as Array<keyof ts.LanguageService>) {
	const x = info.languageService[k]!;
	// @ts-expect-error - JS runtime trickery which is tricky to type tersely
	proxy[k] = (...args: Array<{}>) => x.apply(info.languageService, args);
}

return proxy;

(this is from Writing a Language Service Plugin)

To Reproduce
Steps to reproduce the behavior:

  1. Create a fresh project
  2. Open a project file inside an editor
  3. Change something inside the project's tsconfig.json (it shouldn't matter what option, but I changed the include config value).
  4. (Change / re-open a project file inside the editor)
  5. Debug failure should appear in tsserver logs.

Expected behavior
Debug Failure should not appear in tsserver logs.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: macOS Sequoia 15.2 (24C101)
  • Browser n/a
  • Version [e.g. 22] n/a

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context

tsconfig.json used for fresh project:

{
    "compilerOptions": {
        "allowImportingTsExtensions": true,
        "allowSyntheticDefaultImports": true,
        "isolatedModules": true,
        "verbatimModuleSyntax": true,
        "strict": true,
        "skipLibCheck": false,
        "lib": [
            "esnext"
        ],
        "target": "esnext",
        "module": "nodenext",
        "moduleResolution": "nodenext",
        "baseUrl": "./",
        "rootDir": "./",
        "plugins": [{
            "name": "typescript-plugin-css-modules",
            "options": {
                "customMatcher": "\\.css$",
            }
        }]
    },
    "include": ["./src"]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions