Skip to content

Client requests textDocument/diagnostics before textDocument/didOpen #1718

Closed

Description

@dbaeumer

I don’t know how to reproduce this reliably in a fresh repo, but it’s happening every time I restart the language client/server in my window right now. In the logs, you can see two textDocument/didOpen, followed by textDocument/diagnostic for file:///Users/andrew/Developer/microsoft/typescript-go/Herebyfile.mjs, which is not one of the two that's been already opened. The textDocument/didOpen for Herebyfile.mjs comes later (very end of the logs pasted), and after that, there’s no subsequent textDocument/diagnostic request for it. This must be a bug, because I have unsaved changes in that file's editor, so the didOpen content is going to be different from the text on disk, which is the only thing we could access in order to compute diagnostics.

This actually causes us (TypeScript) to return an error, because from observation we counted on the client only asking for diagnostics for files it’s already opened. But even if we gracefully served the request, the diagnostics shown would be for the wrong content.

2026-02-05 14:51:37.763 [trace] Sending request 'shutdown - (11)'.
2026-02-05 14:51:37.764 [trace] Received response 'shutdown - (11)' in 1ms.
No result returned.
2026-02-05 14:51:37.764 [trace] Sending notification 'exit'.
No parameters provided.
2026-02-05 14:51:37.764 [trace] Received notification 'window/logMessage'.
Params: {
    "type": 3,
    "message": "handled method 'shutdown' (11) in 11.333µs"
}
2026-02-05 14:51:37.766 [trace] Sending request 'initialize - (0)'.
Params: {

}
2026-02-05 14:51:37.775 [trace] Sending notification 'initialized'.
Params: { (removed for brevity) }
2026-02-05 14:51:37.776 [trace] Sending notification 'textDocument/didOpen'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/_packages/api/src/path.ts",
        "languageId": "typescript",
        "version": 59,
        "text": "import { Path } from \"@typescript/ast\";\r\n\r\nconst ..."
    }
}
2026-02-05 14:51:37.776 [trace] Sending notification 'textDocument/didOpen'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/_packages/api/src/node.ts",
        "languageId": "typescript",
        "version": 44,
        "text": "import {\r\n    type Node,\r\n    type NodeArray,\r\n    type SourceFile,\r\n    ..."
    }
}
2026-02-05 14:51:37.776 [trace] Sending request 'textDocument/diagnostic - (1)'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/Herebyfile.mjs"
    }
}
2026-02-05 14:51:37.776 [trace] Sending request 'textDocument/diagnostic - (2)'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/_packages/api/src/path.ts"
    }
}
2026-02-05 14:51:37.776 [trace] Sending request 'textDocument/diagnostic - (3)'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/_packages/api/src/node.ts"
    }
}
2026-02-05 14:51:37.776 [trace] Sending notification 'textDocument/didOpen'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/_packages/api/src/async/api.ts",
        "languageId": "typescript",
        "version": 19,
        "text": "/// <reference path=\"../node.ts\" preserve=\"true\" / ..."
    }
}
2026-02-05 14:51:37.777 [trace] Sending notification 'textDocument/didOpen'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/_packages/api/src/base/api.ts",
        "languageId": "typescript",
        "version": 12,
        "text": "/**\r\n *  ..."
    }
}
2026-02-05 14:51:37.777 [trace] Sending notification 'textDocument/didOpen'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/_packages/api/src/proto.ts",
        "languageId": "typescript",
        "version": 2,
        "text": "export interface ConfigResponse {..."
    }
}
2026-02-05 14:51:37.778 [trace] Sending notification 'textDocument/didOpen'.
Params: {
    "textDocument": {
        "uri": "file:///Users/andrew/Developer/microsoft/typescript-go/Herebyfile.mjs",
        "languageId": "javascript",
        "version": 112,
        "text": "// @ts-check\r\n\r\nimport AdmZip from \"adm-zip\";\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n..."
    }
}

Activity

  1. dbaeumer commented on Feb 6, 2026

    @dbaeumer
    MemberAuthor

    I investigated and here is what I think is happening:

    When you see this happening was the tab for Herebyfile.mjs already full restores / visible ... ?

    The fix for this would be to sent another diagnostic request for Herebyfile.mjs on open even if we have already sent one for the tab. The tab one could be canceled in this scenario.

    I want to point out one thing though: LSP explicitly allows sending requests for document which are not open. The contract then is that a server can use its internal state for the document to fulfil the request.

  2. dbaeumer commented on May 27, 2026

    @dbaeumer
    MemberAuthor

    Dups: #1717

  3. added this to the milestone on Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions