LSP goToDefinition silently drops results in git-ignored paths (.venv, node_modules)

Resolved 💬 3 comments Opened Mar 9, 2026 by zippythrone Closed Mar 19, 2026

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

  1. Any Python project with a .venv managed by uv or standard venv
  2. Install the pyright-lsp plugin
  3. Use goToDefinition on an imported symbol from an external package
  4. 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."
  5. hover on 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:

  1. Extracts file URIs from the LSP response
  2. Runs git check-ignore on those paths
  3. Removes any locations where git check-ignore returns 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)

View original on GitHub ↗

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