[Bug] typescript-lsp plugin: Server starts but textDocument/didOpen never sent

Status Open
Reported on v2.1.1
Maintainer reply None cached
Activity 8 comments · opened Jan 8, 2026

Bug Description

The typescript-lsp@claude-plugins-official plugin initializes the TypeScript Language Server successfully, but never sends textDocument/didOpen notifications when files are read via the Read tool. This results in 0 diagnostics being returned despite the LSP server running correctly.

Environment

  • Claude Code Version: 2.1.1
  • OS: macOS Darwin 25.3.0
  • typescript-language-server: 5.1.3
  • Plugin: typescript-lsp@claude-plugins-official

Evidence from Debug Logs

✅ Server Initialization (WORKS)

[DEBUG] Loaded 1 LSP server(s) from plugin: typescript-lsp
[DEBUG] LSP client started for plugin:typescript-lsp:typescript
[DEBUG] [LSP PROTOCOL] Sending request 'initialize - (0)'.
[DEBUG] [LSP PROTOCOL] Received response 'initialize - (0)' in 56ms.
[DEBUG] LSP server instance started: plugin:typescript-lsp:typescript

✅ Diagnostics Handler Registered (WORKS)

[DEBUG] Registered diagnostics handler for plugin:typescript-lsp:typescript
[DEBUG] Applied queued notification handler for textDocument/publishDiagnostics

❌ textDocument/didOpen (NEVER SENT)

After reading .ts files via Read tool:

  • Zero didOpen in logs
  • Zero diagnostics (LSP Diagnostics: Checking registry - 0 pending)

Reproduction Steps

  1. Enable typescript-lsp@claude-plugins-official
  2. Install typescript-language-server globally
  3. Start Claude Code with --debug
  4. Create test.ts with errors:

``typescript
const x: string = 123;
console.log(undefinedVar);
``

  1. Read file via Read tool
  2. Check logs - no didOpen, no diagnostics

Expected vs Actual

Expected: Read tool → didOpen → LSP analyzes → diagnostics returned
Actual: Read tool → (nothing) → LSP idle → 0 diagnostics

Related Issues

  • #13952, #16291 - Other LSP issues

View original on GitHub ↗

8 Comments

github-actions[bot] · 7 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/15413
  2. https://github.com/anthropics/claude-code/issues/15521
  3. https://github.com/anthropics/claude-code/issues/13952

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

techone-ekucukberber · 7 months ago

didnt they remove lsp tool in 2.1.1?

dselivanov · 7 months ago

Yes, something broken in 2.1.1. - i have same issue. Even after requesting use LSP to go to definition claude uses grep.

mattmcde78 · 7 months ago

I'm experiencing the identical issue with the clangd-lsp plugin. The error message from clangd is explicit about the cause:

Error performing documentSymbol: LSP request 'textDocument/documentSymbol' failed
for server 'plugin:clangd-lsp:clangd': trying to get AST for non-added document

Environment:

  • Claude Code: 2.1.0
  • clangd: 21.1.8
  • OS: Windows 11
  • Plugin: clangd-lsp from claude-code-lsps

Verification that clangd works correctly outside Claude Code:

I wrote a PowerShell script that properly sends the LSP lifecycle messages (initialize → initialized → textDocument/didOpen) and clangd responds correctly, builds ASTs, and indexes the project. The issue is definitively that Claude Code isn't sending didOpen.

Reference implementation: Serena

https://github.com/oraios/serena handles this correctly using a reference-counted context manager pattern in https://github.com/oraios/serena/blob/main/src/solidlsp/ls.py:

# Track open documents
self.open_file_buffers: dict[str, LSPFileBuffer] = {}

# Wrap LSP operations with document lifecycle
with self.open_file(uri):
result = self.document_symbol(uri)

The pattern:

  1. Before any textDocument/* request, check if document is tracked as open
  2. If not open: read file contents, send didOpen notification
  3. If already open: increment ref count (supports nested operations)
  4. On exit: decrement ref count, send didClose when zero

This is memory-efficient (files opened on-demand, not all upfront) and works with any LSP server.

Note: workspace/symbol queries work without opening files (they use the project index), but all textDocument/* operations require the target document to be opened first per the https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didOpen.

nazq · 7 months ago

Linking to #16722 which documents the same underlying issue from a different angle.

Our issue shows the LSP tool existed in v2.0.74 (per official changelog) and was removed in v2.1.1 (per prompt diff analysis). Your diagnosis of the missing textDocument/didOpen explains why it was pulled.

The evidence chain:

  1. LSP servers connect and initialize correctly (confirmed across rust-analyzer, TypeScript LSP, jdtls, clangd)
  2. Diagnostics work (pushed by server, no didOpen required)
  3. Navigation tools fail (require didOpen per LSP spec)
  4. Tool was removed rather than fixed

Your Serena reference implementation is the right pattern. Hopefully this gets prioritized - multiple users across different language servers are hitting the same wall.

— Claude

joseph0063 · 6 months ago

having same issur would very usefull to have lsp working on cc

wellofspirit · 6 months ago

Can confirm this is the issue.
My Claude code writes a script from command line verifies that textDocument/didOpen is not sent by LSP client

GangsanJeong · 5 months ago

Still having issues of never sending textDocument/didOpen in v2.1.69. Tested with clangd-lsp.