[BUG] LSP goToDefinition drops files in .venv

Status Closed — not planned
Reported on v2.1.193
Maintainer reply ✓ Yes — bcherny
Activity 6 comments · opened Jun 30, 2026 · closed Sep 14, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

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?

I am using the Claude Code (CC) LSP plugin with the Python ty language server. When Opus runs the language server's goToDefinition on symbols that have their definition in the virtual environment (.venv folder in my repo), Opus gets back "0 definitions" and cannot use the language server to navigate to the definition, although the language server correctly returns the definitions. The reason for this is that the CC harness filters out paths that are in the .gitignore file. Obviously, the virtual environment folder is always in the .gitignore file.

This means that the LSP plugin is only half useful. Its goToDefinition and other commands only work correctly on my own code, not on any libraries I am using.

What Should Happen?

Opus should be able to read code in the virtual environment (all third party packages I am using in my project) to understand it and craft code that uses the libraries in the virtual environment. In fact, when using the language server with my code editor manually, I use its goToDefinition to look at code in the virtual environment all the time.

Opus can use find, grep, etc. to get to the code definition, so there is no reason it shouldn't be able to do the same using the LSP plugin.

Error Messages/Logs

Steps to Reproduce

  1. Setup simple python project with .venv folder in the repo root (default location) and install some libraries.
  2. Create .gitignore file that includes .venv.
  3. Setup Claude Code LSP plugin with e.g. ty language server or pyright language server.
  4. Create a Python module that imports something from the virtual environment.
  5. Tell Claude Code to check if goToDefinition with the LSP plugin works for symbols in the virtual environment.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.46

Claude Code Version

2.1.193

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

The behavior was apparently correct initially, until the following Github issue called it a bug: https://github.com/anthropics/claude-code/issues/26051

Apparently the Github issue led to a code change that now produces the wrong behavior described above.

Two other Github issues are also calling for the behavior that I expect (no filtering, or at least a way to opt out of filtering):

Those two have been closed without explanation.

View original on GitHub ↗

6 Comments

akbo · 3 months ago

This regression seems to come from #26051, and that issue shows where the fix overreached.

That issue was a valid complaint about findReferences returning matches inside .gitignore'd paths (.venv, vendored code, etc.), which is noise. The fix — make LSP results respect .gitignore — is reasonable for findReferences. The problem is the same filter was applied to goToDefinition, where the meaning is the opposite.

The two operations answer different questions:

  • findReferences / workspaceSymbol: "Where in MY project is this used?" Filtering gitignored paths is correct here — hits inside .venv are noise the user didn't write.
  • goToDefinition: "Where is the ONE canonical place this is defined?" Filtering is wrong here — for any imported third-party symbol, the definition IS in a dependency (.venv/site-packages/stdlib), which is gitignored. So the filter doesn't remove noise; it removes the only correct answer.

Suggested fix: apply the .gitignore filter only to enumeration operations (findReferences, workspaceSymbol), and not to single-target navigation (goToDefinition, goToImplementation). Those should return the resolved location even when it points outside the workspace root.

Also, it might make sense to make this behavior configurable.

bcherny collaborator · 1 month ago

Confirmed — reproduced on 2.1.233 (Linux), regression since 2.1.47.

Setup: python project with .venv (gitignored) + pyright LSP plugin. goToDefinition on a symbol defined in the repo works, but on requests.get (definition inside .venv) the tool reports "No definition found" even though the language server returns the location — it's dropped because the path is gitignored. Notably, definitions resolved outside the repo (e.g. global site-packages) come through fine; only in-repo gitignored paths are dropped.

This filtering was introduced in 2.1.47 to cut noise from gitignored files in reference results (#26051), but for goToDefinition the gitignored location is usually the only result, so filtering it breaks navigation into libraries and the "not indexed by the LSP server" message is misleading. We're looking at exempting definition-style lookups from the gitignore filter while keeping the noise reduction for multi-result operations.

🤖 Generated with Claude Code

github-actions[bot] · 1 month ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

onnimonni · 21 days ago

This was auto-closed as stale, but it still happens in 2.1.280. I opened #96262 as the bot asked, with a new reproduction: Elixir deps/ with the Dexter LSP. There, goToDefinition and workspaceSymbol both drop results that the language server returns. The filter is still unconditional in the bundle, and no setting turns it off.

marcindulak · 21 days ago

This issue was incorrectly closed by the github-actions bot, despite having reproduction steps and Claude version. This bot behavior is tracked in https://github.com/anthropics/claude-code/issues/87647. Consider upvoting that issue for visibilty, maybe the bot behavior gets fixed.

asvishnyakov · 21 days ago

Reopen issue please, it's still relevant