Skip to content

🐛 fix(lsp): build valid file URIs on Windows using URIFromPath#82

Open
LaelLuo wants to merge 1 commit into
isaacphi:mainfrom
LaelLuo:fix/windows-file-uri
Open

🐛 fix(lsp): build valid file URIs on Windows using URIFromPath#82
LaelLuo wants to merge 1 commit into
isaacphi:mainfrom
LaelLuo:fix/windows-file-uri

Conversation

@LaelLuo
Copy link
Copy Markdown

@LaelLuo LaelLuo commented Sep 16, 2025

Fix frequent 'not found' in tools on Windows by constructing valid file URIs:

  • Use protocol.URIFromPath for didOpen/didChange/didClose, RootURI, WorkspaceFolders (avoids two-slash + backslash URIs)
  • Convert DocumentUri back to OS paths via DocumentUri.Path() when closing files
  • Update tools (hover, rename_symbol, diagnostics, codelens) to use proper URIs
  • Update watcher to emit proper file URIs

Rationale
Invalid URIs like 'file://C:\path' can be ignored by LSP servers (e.g., typescript-language-server), preventing indexing and causing 'not found' responses. This change normalizes URIs to 'file:///C:/path' and forward slashes, per LSP spec.

Build: go build ./... passes.
Tests: Root go test passes; integration tests depend on external language servers.

- Use protocol.URIFromPath for all file URIs (didOpen/didChange/didClose, RootURI, WorkspaceFolders)
- Convert DocumentUri back to OS path via DocumentUri.Path() when closing files
- Update tools (hover, rename_symbol, diagnostics, codelens) to use proper URIs
- Fix watcher to emit proper file URIs

Rationale: previously URIs like 'file://C:\\path' (with backslashes/two slashes) could be invalid for LSP servers like typescript-language-server, causing requests (e.g. workspace/symbol and opened files) to be ignored, leading to frequent 'not found' results on Windows
STRd6 pushed a commit to STRd6/mcp-language-server that referenced this pull request May 14, 2026
Replaces every "file://"+path and TrimPrefix(uri,"file://") with
protocol.URIFromPath / DocumentUri.Path() across the LSP client,
watcher, tools, and edit utilities. On Linux paths these produce
identical strings, but Windows paths (with backslashes / drive
letters) previously yielded URIs like file://C:\foo that some
servers (notably typescript-language-server) silently rejected,
which surfaced as "not found" responses on workspace/symbol and
opened-file requests.

Adapted from upstream PR isaacphi#82 (LaelLuo).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
STRd6 pushed a commit to STRd6/mcp-language-server that referenced this pull request May 14, 2026
Two bugs introduced when adapting upstream PR isaacphi#82 to use
DocumentUri.Path() instead of strings.TrimPrefix("file://"):

- pattern_interfaces.go now calls .Path() unconditionally on the
  BaseURI string, which panics if the LSP sends a value without
  the file:// scheme. Guard the call with a HasPrefix check and
  fall back to using the raw string as a path.

- watcher.matchesPattern was calling .Path() a second time on the
  basePath returned by pattern_interfaces.GetBasePath(), which
  has already been converted to a filesystem path. The original
  TrimPrefix happened to be idempotent; .Path() is not, and
  panics on a plain path. Drop the redundant call.

Surfaced by rust-analyzer integration tests, which are the only
LSP in our matrix that emits a RelativePattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
STRd6 pushed a commit to STRd6/mcp-language-server that referenced this pull request May 14, 2026
Two CI failures on 54ec662, both reproducible only against gopls
(the local test pass before push missed them because gopls was not
installed):

- tools.go:19 was an infinite recursive call in mcpServer.addTool.
  The bulk rename of s.mcpServer.AddTool -> s.addTool in 54ec662
  rewrote the call inside the helper itself, so every tool invocation
  recursed into the gate. staticcheck SA5007 caught it; reverted that
  one call back to s.mcpServer.AddTool.

- edit_file.go was constructing a WorkspaceEdit key via
  protocol.DocumentUri(filePath) -- raw cast, no scheme. The PR isaacphi#82
  edit_file.go ApplyTextEdits adaptation in utilities/edit.go is now
  uri.Path() instead of TrimPrefix("file://"), and Path() panics on a
  non-file URI. Fix the construction site (use URIFromPath) and make
  utilities/edit.go defensive via a uriToPath helper that falls back
  to the raw string when the prefix is missing, so an analogous bug
  surfaces as a file-not-found error rather than a runtime panic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant