LSP goToDefinition silently drops results in git-ignored paths (.venv, node_modules)
Summary
The LSP tool's goToDefinition (and goToImplementation) operations silently filter out results that point to files in git-ignored directories (e.g., .venv/, node_modules/). This makes it impossible to navigate to definitions in external packages.
Reproduction
- Any Python project with a
.venvmanaged byuvor standardvenv - Install the pyright-lsp plugin
- Use
goToDefinitionon an imported symbol from an external package - Result: "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."
hoveron the same symbol works correctly — showing full type info and docstring
Root Cause
In the LSP tool's call handler, results from goToDefinition, findReferences, goToImplementation, and workspaceSymbol are passed through a filter that:
- Extracts file URIs from the LSP response
- Runs
git check-ignoreon those paths - Removes any locations where
git check-ignorereturns exit code 0
Since .venv/ is typically git-ignored (both by project .gitignore and by .venv/.gitignore auto-generated by venv/uv which contains *), all definitions in external packages are silently dropped.
The hover operation is unaffected because it is not routed through this filter.
Suggested Fix
Add a configuration option to control the git check-ignore filtering behavior per LSP operation. For example, a setting like:
// .claude/settings.json or similar
{
"lsp": {
"gitIgnoreFilter": {
"goToDefinition": false,
"goToImplementation": false,
"findReferences": true,
"workspaceSymbol": true
}
}
}
The default could remain as-is for backwards compatibility, but users working with external dependencies should be able to opt out of the filter for navigation operations like goToDefinition and goToImplementation, which return a small number of precise results (usually 1) where filtering adds no value.
The relevant code path (from compiled binary analysis):
// Current: unconditionally filters all these operations through git-ignore check
if (M && Array.isArray(M) && (
H.operation === "findReferences" ||
H.operation === "goToDefinition" ||
H.operation === "goToImplementation" ||
H.operation === "workspaceSymbol"
)) {
// ... runs git check-ignore, drops ignored paths
}
Environment
- Claude Code v2.1.71
- pyright-lsp plugin v1.0.0
- pyright v1.1.408
- Python 3.13.11
- uv 0.9.26
- Ubuntu 24.04.4 LTS (WSL2)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗