microsoft / microsoft/pyright

False Unreachable Code Detection on Startup - Gets Fixed by LSP Restart

Open
#10,936 2 comments 0 reactions 0 assignees View on GitHub
bug needs investigation
Dominant language
Python
Stars
15.6k
Forks
1.8k
Avg merge
12h 13m
Merged PRs (30d)
52

Description

# False Unreachable Code Detection on Startup - Fixed by LSP Restart

## Describe the bug

Pyright incorrectly marks valid Python code as "unreachable" (grayed out with diagnostic warnings) when first opening files in Neovim. This issue occurs consistently on startup but is immediately resolved by running `:LspRestart pyright`. The problem suggests an initialization or state management issue rather than actual unreachable code.

**Observed behavior:**
- Valid Python code is marked as unreachable with gray highlighting on first file open
- Third-party library navigation works correctly (indicating Python path detection is functional)
- Issue affects all Python files in the project consistently

**Expected behavior:**
- Valid Python code should not be marked as unreachable on initial LSP startup
- Code reachability analysis should be accurate from the first initialization

**Steps to reproduce:**
1. Open a Python file in Neovim with Pyright LSP configured
2. Open any Python file in the project
3. Observe valid code marked as unreachable (grayed out)
4. Run `:LspRestart pyright` in Neovim
5. Notice that the unreachable code warnings disappear immediately

## Code or Screenshots

Here's a minimal example that demonstrates the issue:

```python
# This code gets marked as unreachable on startup but works after LSP restart

def retry_onboard(self, request: Request, merchant_id: str):
maybe_onboard.delay(id=id)
serializer = self.get_serializer(data={"message": "Retrying onboarding"})
# These following lines gets grayed out on startup
serializer.is_valid(raise_exception=True)
return Response(serializer.data, status=status.HTTP_200_OK)

def calculate_sum(a: int, b: int) -> int:
"""Simple function that should never be marked unreachable."""
serializer = serializer.get_response()
# This following lines gets grayed out on startup
return result

if __name__ == "__main__":
# This entire block gets grayed out on startup
value = calculate_sum(5, 10)
print(f"Result: {value}")
```

The code above is perfectly valid and executable, but Pyright marks the entire `if __name__ == "__main__":` block and sometimes the function body as unreachable on first load.

## VS Code extension or command-line

**Environment:**
- Pyright version: 1.1.389
- Python version: 3.13.0 (managed via pyenv)
- OS: macOS (Darwin 24.6.0)
- Editor: Neovim with nvim-lspconfig
- Python environment: pyenv with virtual environments

**Neovim LSP Configuration:**
```lua
pyright = {
settings = {
python = {
analysis = {
typeCheckingMode = "basic",
autoSearchPaths = true,
useLibraryCodeForTypes = true,
autoImportCompletions = true,
indexing = true,
packageIndexDepths = {
{
name = "",
depth = 2,
includeAllSymbols = true,
},
},
},
pythonPath = os.getenv("VIRTUAL_ENV") and (os.getenv("VIRTUAL_ENV") .. "/bin/python") or "python",
executionEnvironments = {
{
root = ".",
},
},
},
},
},
```

## Additional Context

- Third-party library imports and navigation work correctly, indicating path resolution is successful
- The problem only affects the initial startup - once restarted using `:LspRestart pyright`, Pyright works perfectly until the next editor session
- No errors appear in the LSP logs during the problematic startup phase
- Virtual environment detection appears to work correctly (can navigate to installed packages)

This suggests incomplete initialization during Pyright's startup process, where the unreachable code analysis runs before all context is properly loaded or configured.

## Workaround

Running `:LspRestart pyright` in Neovim immediately resolves the issue, but this needs to be done for every new editor session, which disrupts the development workflow.

Contributor guide

Open the contributing guide

Research direction

The issue names no source files or tests; start by reproducing the startup behavior with the reported Neovim configuration and compare diagnostics before and after an LSP restart. Trace initialization and reachability diagnostics until the initial analysis matches the restarted result, then verify that valid code is not marked unreachable on first open.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.