[BUG] LSP clangd fails on Windows: "unresolvable URI" in textDocument/didOpen

Resolved 💬 1 comment Opened Jan 9, 2026 by kterzides Closed Jan 11, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Disclaimer:

  • The following was auto-generated by Claude-code

Environment

  • Claude Code Version: 2.1.2
  • OS: Windows 10/11 (MINGW64_NT-10.0-26200)
  • LSP Plugin: clangd-lsp@claude-plugins-official v1.0.0
  • clangd Version: 19.1.5 (from MinGW)

Summary

The clangd LSP plugin fails to register documents on Windows due to improper file URI formatting. Claude Code's LSP client sends Windows-style paths (C:\Users\...) to clangd without converting them to proper file URIs (file:///C:/Users/...), causing clangd to reject the textDocument/didOpen request.

Root Cause

The LSP client in Claude Code v2.1.2 doesn't properly convert Windows file paths to LSP-compliant file URIs before sending textDocument/didOpen notifications to language servers.

According to the LSP specification, the uri field must be a valid URI (RFC 3986), which for local files should be:

  • Correct: file:///C:/Users/username/project/src/main.cpp
  • Incorrect: C:\Users\username\project\src\main.cpp

Impact

This bug affects all Windows users trying to use any LSP plugin (not just clangd). The issue likely affects:

  • clangd-lsp (C/C++)
  • pyright-lsp (Python)
  • typescript-lsp (TypeScript)
  • rust-analyzer-lsp (Rust)
  • And all other LSP plugins on Windows

This explains why some users reported LSP working (likely on macOS/Linux) while others couldn't get it working (Windows users).

Related Issues

  • #15168 - LSP plugin system not connecting to language servers
  • #13952 - LSP servers not loading due to race condition (different issue, but related confusion)
  • #14803 - LSP plugins not recognized

Proposed Fix

The LSP client needs to convert Windows file paths to proper file URIs before sending them to language servers. This conversion should:

  1. Replace backslashes with forward slashes: C:\Users\...C:/Users/...
  2. Add the file URI scheme: C:/Users/...file:///C:/Users/...
  3. Properly URL-encode any special characters in the path

Example TypeScript implementation:

function toFileUri(filePath: string): string {
  if (process.platform === 'win32') {
    // Convert backslashes to forward slashes
    const normalizedPath = filePath.replace(/\\/g, '/');
    // Add file:// scheme (triple slash for absolute paths)
    return `file:///${normalizedPath}`;
  }
  // Unix-like systems
  return `file://${filePath}`;
}

Configuration Details

Plugin is properly installed and enabled:

// ~/.claude/settings.json
{
  "enabledPlugins": {
    "clangd-lsp@claude-plugins-official": true
  }
}

clangd initializes successfully:

2026-01-08T13:38:59.873Z [DEBUG] [LSP SERVER plugin:clangd-lsp:clangd] I[15:38:59.861] clangd version 19.1.5
2026-01-08T13:38:59.955Z [DEBUG] LSP server plugin:clangd-lsp:clangd initialized

The issue is purely in the URI formatting when sending textDocument/didOpen.

Workaround

None currently available. The bug is in Claude Code's LSP client, not in user configuration.

Downgrading to v2.0.67 (last known working LSP version) is not recommended as it has the race condition bug (#13952) that prevents LSP from loading at all.

Additional Notes

  • The clangd binary works perfectly with LunarVim and VS Code on the same machine
  • Indexes are being built correctly at .cache/clangd/index/
  • The compile_commands.json exists and is valid
  • This is a Windows-specific bug in the LSP client implementation

What Should Happen?

Expected Behavior

  1. clangd receives properly formatted file URI: file:///C:/Users/username/project/src/main.cpp
  2. textDocument/didOpen succeeds
  3. Document is registered with clangd
  4. LSP operations (prepareCallHierarchy, goToDefinition, etc.) work correctly

Actual Behavior

  1. clangd receives improperly formatted URI
  2. textDocument/didOpen fails with error: Failed to decode textDocument/didOpen request: unresolvable URI at (root).textDocument.uri
  3. Document is NOT registered with clangd
  4. All subsequent LSP operations fail with: trying to get AST for non-added document

Error Messages/Logs

## Debug Logs
From `~/.claude/debug/<session>.txt`:


2026-01-08T13:40:40.671Z [DEBUG] [LSP PROTOCOL plugin:clangd-lsp:clangd] Sending notification 'textDocument/didOpen'.
2026-01-08T13:40:40.671Z [DEBUG] LSP: Sent didOpen for C:\Users\username\project\src\main.cpp (languageId: cpp)
2026-01-08T13:40:40.672Z [DEBUG] [LSP PROTOCOL plugin:clangd-lsp:clangd] Sending request 'textDocument/prepareCallHierarchy - (1)'.
2026-01-08T13:40:40.672Z [DEBUG] [LSP SERVER plugin:clangd-lsp:clangd] I[15:40:40.673] <-- textDocument/didOpen
2026-01-08T13:40:40.673Z [DEBUG] [LSP SERVER plugin:clangd-lsp:clangd] E[15:40:40.674] Failed to decode textDocument/didOpen request: unresolvable URI at (root).textDocument.uri
2026-01-08T13:40:40.674Z [DEBUG] [LSP SERVER plugin:clangd-lsp:clangd] I[15:40:40.675] <-- textDocument/prepareCallHierarchy(1)
2026-01-08T13:40:40.675Z [DEBUG] [LSP SERVER plugin:clangd-lsp:clangd] I[15:40:40.675] --> reply:textDocument/prepareCallHierarchy(1) 0 ms, error: -32602: trying to get AST for non-added document


**Key line**: `LSP: Sent didOpen for C:\Users\username\project\src\main.cpp (languageId: cpp)`

This shows Claude Code is sending the Windows backslash path format directly, which violates the LSP specification requiring file URIs.

Steps to Reproduce

Steps to Reproduce

  1. Install clangd LSP plugin: /plugin install clangd-lsp@claude-plugins-official
  2. Ensure clangd is installed and in PATH (verify with clangd --version)
  3. Have a C++ project with compile_commands.json in the project root
  4. Open a C++ file in VS Code (or any editor)
  5. Use Claude Code's LSP tool: LSP with operation prepareCallHierarchy on any C++ file

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.2

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗