LSP tool: workspaceSymbol needs a query parameter

Open 💬 24 comments Opened Mar 5, 2026 by ratchanonp

Problem

The LSP tool's workspaceSymbol operation does not work because the tool interface has no way to pass a query string, which is required by the LSP workspace/symbol request.

All 9 LSP operations share the same parameter interface:

filePath: string
line: number
character: number

This maps correctly to TextDocumentPositionParams for 8 operations (goToDefinition, findReferences, hover, documentSymbol, goToImplementation, prepareCallHierarchy, incomingCalls, outgoingCalls).

However, workspaceSymbol uses a fundamentally different request shape per the LSP spec:

interface WorkspaceSymbolParams {
  query: string;  // <-- no way to pass this through the current interface
}

As a result, the tool always sends an empty query, and language servers (e.g., gopls) correctly return no results for empty queries.

Evidence

gopls CLI works perfectly:

$ gopls workspace_symbol Reconcile
# Returns 30+ matching symbols across the workspace

Claude Code LSP tool always returns empty:

LSP(operation: "workspaceSymbol", filePath: "main.go", line: 1, character: 1)
→ "No symbols found in workspace"

Tested with cursor positioned on known symbols (Reconcile, SetupWithManager, kubernetesClusterReconciler) — all return empty. The filePath/line/character params are not used to derive a query.

Environment

  • Claude Code (CLI)
  • gopls v0.21.1 (fully indexed, all other LSP operations work)
  • Go 1.25.3
  • macOS

Proposed Solution

Add an optional query parameter to the LSP tool, used when operation is workspaceSymbol:

{
  operation: "workspaceSymbol",
  filePath: string,    // still needed to identify the workspace/LSP server
  line: number,        // ignored for workspaceSymbol
  character: number,   // ignored for workspaceSymbol
  query?: string,      // NEW: the symbol search query
}

When operation === "workspaceSymbol", the tool would send:

{ "query": "<value of query param>" }

instead of the current TextDocumentPositionParams.

Workaround

Currently using Grep with regex patterns (e.g., func.*Reconcile across *.go files) as a substitute, but this lacks type information and cross-package awareness that workspaceSymbol provides.

View original on GitHub ↗

24 Comments

pdebuitlear · 4 months ago

reproduces on v2.1.71

PyGeek03 · 4 months ago

I'm hitting this with pyright LSP on v2.1.71 as well.

dpearson2699 · 4 months ago

Same issue with Swift-LSP on stable CC version 2.1.58

dergachoff · 4 months ago

upvoting for visibility. LSP is too useful to be neglected

detinho · 4 months ago

Same here using jdtls

githoober · 4 months ago

This effectively renders LSP semi-useless. +1

pdebuitlear · 4 months ago

reproduces on v2.1.78

Gh0st99 · 3 months ago

reproduces on v2.1.80

oshinsky · 3 months ago

reproduces on v2.1.81

kasbohm · 3 months ago

Reproduces on v2.1.84, the same issue exists with pyright.

yurukusa · 3 months ago

Good catch on the parameter mismatch. Until Anthropic adds a query parameter to workspaceSymbol, here are alternatives:
Workaround 1 — Use Grep/Glob instead:
For finding symbols by name, Grep and Glob are often more reliable than LSP workspace symbols:

<!-- CLAUDE.md -->
When searching for symbols by name, prefer Grep over LSP workspaceSymbol.
Example: to find a class named "UserService", use Grep with pattern "class UserService"

Grep searches file contents directly and doesn't depend on LSP parameter formats.
Workaround 2 — Use documentSymbol per file:
documentSymbol works correctly (it uses the standard filePath parameter). You can achieve workspace-level symbol search by:

  1. Glob for relevant files: **/*.ts, **/*.py
  2. Run documentSymbol on each file

This is less efficient than workspaceSymbol but functionally equivalent.
Workaround 3 — Use the Bash tool with LSP CLI tools:
If you have language-specific tools installed:

npx typescript-language-server --stdio << 'EOF'
{"method":"workspace/symbol","params":{"query":"UserService"}}
EOF
rg "^(class|function|def|interface)\s+UserService" --type-add 'code:*.{ts,py,go}' -t code

Workaround 4 — ctags/etags as a fallback:

ctags -R .
grep "UserService" tags

Classical but reliable for symbol lookup without LSP.

pdebuitlear · 3 months ago

Still reproducing on v2.1.87

pdebuitlear · 3 months ago

still reproducing in v2.1.97

SpiGAndromeda · 3 months ago

still in 2.1.107

dragonfax · 3 months ago

Still happens. Makes LSP useless, as the agent is usually going to start with a workspaceSymbol call when it doesn't yet have a class or file for a given function name.

pdebuitlear · 3 months ago

Claude code is lagging behind kiro cli with regards to LSP

dragonfax · 2 months ago

Still there, version 2.1.114

This is pretty serious lacking for Claude code, I have to admit. This tends to be a root function call for source code exploration. One of the earliest things that the agent is going to try to use when it attempts LSP.

This is a major issue because this is going to fail for f performing the task the agent wants. This is gonna tell it that the LSP is not working and it's always gonna fall back to using traditional bash and read tools. thus getting no benefit from the LSP.

And of course token inertia is going to keep it from trying the LSP again for other tasks. It's just going to stick with the built-in bash and read tools.

dragonfax · 2 months ago

I did try forcing the agent to include a query parameter, but the internal JSON schema validator seems to reject that.

devdev999 · 2 months ago

Still happening as of latest CC

jose-bittacora · 2 months ago

Still happening

pdebuitlear · 2 months ago

This is not fixed for workspaceSymbol using jdtls on windows, all other LSP tools work in jdtls using Claude Code v2.1.138 except workspaceSymbol.

freeformz · 1 month ago

So this is why my LSPs really don't seem to do anything except code issues after save. :-(

62mkv · 1 month ago

is it correct that issue only occurs on MacOS? does not sound like that based on comments

detinho · 1 month ago
is it correct that issue only occurs on MacOS? does not sound like that based on comments

Same behavior on windows.