[BUG] LSP goToDefinition drops definitions in git-ignored dependency folders (deps/, .venv, node_modules): reopen of #72594

Status Open
Reported on v2.1.280
Maintainer reply None cached
Activity 3 comments · opened Sep 23, 2026

Preflight Checklist

  • [x] I have searched existing issues. This is the bug from #72594 and #76371, which a maintainer confirmed and said a fix was being looked at. Both were then auto-closed as stale, so I am opening a new issue as the bot asked.
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code available to me (2.1.280)

What's Wrong?

The LSP tool drops every goToDefinition, goToImplementation, findReferences and workspaceSymbol location whose path git check-ignore reports as ignored. For dependencies installed inside the project, the definition is always in an ignored folder: Elixir deps/, Python .venv/, JS node_modules/. Go-to-definition into a library therefore always reports:

No definition found. This may occur if the cursor is not on a symbol, or if the definition is in an external library not indexed by the LSP server.

The language server did return the location, so the hint points the wrong way. hover on the same position works, because it carries no URI, which makes this look like a language server bug.

Filtering ignored paths makes sense for findReferences and workspaceSymbol, where hits inside dependencies are noise. For goToDefinition and goToImplementation, the ignored location is usually the only correct answer.

What Should Happen?

goToDefinition and goToImplementation should return definitions in ignored paths. Alternatively, a setting could turn the filter off, or the tool could say that N results were hidden because they are git-ignored.

Steps to Reproduce

Elixir project with /deps/ in .gitignore, using the Dexter LSP plugin (dexter-lsp, Dexter 0.7.2):

  1. Run the LSP tool goToDefinition on Ecto.Multi.new() or Phoenix.PubSub.broadcast(...) in lib/.
  2. Result: "No definition found."
  3. hover at the same position returns the function's docs.
  4. workspaceSymbol with query Ecto.Multi.new returns "No symbols found in workspace."

Driving dexter lsp directly over stdio at the same positions returns the locations:

textDocument/definition => [{"uri":"file:///.../deps/ecto/lib/ecto/multi.ex","range":{"start":{"line":177,"character":0},...}}]
workspace/symbol        => Ecto.Multi.new/0 file:///.../deps/ecto/lib/ecto/multi.ex

Controls in the same session:

  • Enum.group_by resolves, because the Elixir stdlib is in /nix/store, outside the repo, where git check-ignore does not apply.
  • Definitions in lib/ resolve.

Where it happens

In the 2.1.280 bundle, after sendRequest, the tool runs this when the operation is findReferences, goToDefinition, goToImplementation or workspaceSymbol:

if (F && Array.isArray(F) && (n.operation==="findReferences" || n.operation==="goToDefinition" || n.operation==="goToImplementation" || n.operation==="workspaceSymbol"))
  // ... $p(locations, cwd) runs `git check-ignore <paths...>` in batches of 50
  // and removes every location whose path is printed

No setting or environment variable guards it, so users have no workaround short of un-ignoring their dependency folders.

Is this a regression?

Yes. According to the maintainer comment on #72594, it started in 2.1.47 with the fix for #26051.

Claude Code Version

2.1.280 (Claude Code)

Operating System

macOS 26.6, arm64

Additional Information

Related: #72594 (.venv, confirmed and reproduced by a maintainer), #76371 (same filter hides .claude/worktrees/), #26051 (the original request to filter references).

View original on GitHub ↗

3 Comments

onnimonni · 21 days ago

Prior reports of this same filter, both confirmed by a maintainer and then auto-closed as stale: #72594 (.venv) and #76371 (.claude/worktrees/). The filter was introduced for #26051.

marcindulak · 21 days ago

Please note that this issue is on its way to be auto-closed too, like the other ones.

To prevent this issue from getting stale, you would need to comment every time before the 14 days interval expires. See https://github.com/anthropics/claude-code/issues/87647 for more details and consider upvoting that for visibility.

christhonie · 18 days ago

The same filter has a second failure mode. It drops the project's own source code, not just dependencies, whenever the file sits in a nested git repository. The fix proposed here (stop filtering goToDefinition and goToImplementation) would not cover it, so I'm adding it here instead of opening a duplicate.

Cause. The filter runs git check-ignore from the directory Claude Code was launched in. That applies the launch repository's ignore rules to every result, even when a file belongs to a different repository nested below it.

Setup. This is a common multi-repo workspace: one small repo holds shared tooling, and the service repos are separate clones inside it.

~/ws/                  <- git repo, launch directory
  .gitignore           <- "/*/"  (sibling clones are not content of this repo)
  service/             <- separate git clone, Maven project

Reproduce (Claude Code 2.1.283, WSL2, jdtls 1.61 via jdtls-lsp@claude-plugins-official):

  1. Run cd ~/ws && claude.
  2. Run the LSP tool on any .java file under service/.
  3. findReferences on a class with 53 usages returns "No references found".
  4. goToDefinition on a call to a method in the same file returns "No definition found".
  5. workspaceSymbol returns "No symbols found in workspace".
  6. hover, documentSymbol and incomingCalls/outgoingCalls work, which points the investigation at jdtls instead of the tool.

git check-ignore ~/ws/service/src/.../Foo.java exits 0 from ~/ws, because /*/ matches. From ~/ws/service, the repository that actually contains the file, it exits 1. Adding !/service/ to ~/ws/.gitignore makes all four operations return correct results immediately, in the same session and without restarting the server. cd service in the Bash tool does not help, because the filter uses the launch directory.

Suggested fix, complementary to the one above. Judge each location by the repository that contains it: git -C <dirname of file> check-ignore -- <file>, or group the locations by git rev-parse --show-toplevel. A file inside a nested repository should never be filtered by an outer repository's .gitignore. The filter would still hide target/ and node_modules/, through the nested repository's own ignore rules.

This is probably also why #76371 bit Claude Code's own worktrees: a worktree under .claude/worktrees/ is judged by the parent checkout's rules instead of its own.

+1 to reporting "N results hidden (git-ignored)" rather than the current "not indexed / external library" hint. That hint made this look like a language server problem, and it is not one.