LSP bridge: goToDefinition, findReferences, workspaceSymbol always return empty

Resolved 💬 3 comments Opened Apr 7, 2026 by miw1513 Closed Apr 11, 2026

Bug Description

The built-in LSP bridge (gopls-lsp, typescript-lsp plugins) returns empty results for goToDefinition, findReferences, goToImplementation, and workspaceSymbol, while hover, documentSymbol, and incomingCalls/outgoingCalls work correctly at the same cursor position.

Environment

  • Claude Code: latest (CLI)
  • macOS Darwin 25.3.0 (Apple Silicon)
  • gopls v0.21.1
  • typescript-language-server v5.1.3
  • Go 1.26.0, Node 22.19.0

Steps to Reproduce

  1. Install gopls-lsp@claude-plugins-official
  2. Open a Go project with go.work (multi-module)
  3. Use the LSP tool:
  • hover at any symbol → works (returns type info, docs)
  • documentSymbolworks (lists all symbols)
  • incomingCallsworks (finds callers cross-file)
  • goToDefinition at same position → returns empty ("No definition found")
  • findReferences at same position → returns empty ("No references found")
  • workspaceSymbolreturns empty ("No symbols found")

Same behavior with typescript-lsp plugin.

Root Cause Analysis

Tested gopls directly via Python LSP client with identical parameters:

# Direct gopls test — ALL operations work
goToDefinition: ✅ returns correct location (line 20)
findReferences: ✅ 26 locations found
workspaceSymbol: ✅ 100 matches found

The gopls logs show:

  1. gopls sends window/showMessage: "Loading packages..." notification
  2. ~400ms later, sends "Finished loading packages."
  3. Then returns the actual result

The Claude Code LSP bridge appears to not wait for gopls to finish loading packages before reading the response. It likely reads the first response (which is a notification, not the result) and interprets the missing id match as "not found."

Operations that work (hover, documentSymbol, incomingCalls) likely trigger textDocument/didOpen internally, which forces gopls to create a file "view" synchronously. But goToDefinition/findReferences/workspaceSymbol require the full workspace to be indexed first.

Workaround

Built an MCP server (lsp-bridge) that wraps gopls/typescript-language-server/pyright with proper initialization timing — waits for "Finished loading" before sending requests. All operations work correctly through this wrapper.

Expected Behavior

All LSP operations should return correct results, matching what the language server returns when called directly.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗