Skip to content

Fix bundled LSP paths always inserted at front of sys.path regardless of importStrategy#584

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/fix-sys-path-ordering
Draft

Fix bundled LSP paths always inserted at front of sys.path regardless of importStrategy#584
Copilot wants to merge 2 commits intomainfrom
copilot/fix-sys-path-ordering

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 11, 2026

When importStrategy is "fromEnvironment", bundled libs/ was appended to sys.path, allowing user-installed packages to shadow pygls, lsprotocol, cattrs, and typing_extensions — crashing the LSP server on startup.

Changes

  • lsp_server.py / lsp_runner.py: Replaced the update_sys_path function (which conditionally appended vs. inserted based on strategy) with unconditional sys.path.insert(0, ...) for bundled paths. User environments can still provide their own isort via the interpreter's default path; only LSP infrastructure is locked to bundled.

    # Before — appended when strategy == "fromEnvironment"
    update_sys_path(
        os.fspath(pathlib.Path(__file__).parent.parent / "libs"),
        os.getenv("LS_IMPORT_STRATEGY", "useBundled"),
    )
    
    # After — always first, regardless of strategy
    _bundled_libs = os.fspath(pathlib.Path(__file__).parent.parent / "libs")
    if _bundled_libs not in sys.path and os.path.isdir(_bundled_libs):
        sys.path.insert(0, _bundled_libs)
  • lsp_utils.py: Added ImportError to contextlib.suppress in _run_module so that any import failure that still slips through degrades gracefully instead of propagating up to crash the server.

script_runner.py and _debug_server.py each have their own update_sys_path copies and are left untouched.

Original prompt

Problem

When importStrategy is "fromEnvironment", the bundled libs/ path is appended to the end of sys.path. User-installed packages (e.g. via pip install -r requirements.txt) can shadow the extension's bundled LSP dependencies (pygls, lsprotocol, cattrs, typing_extensions), causing import failures that crash the server.

This is the root cause behind multiple recurring crash issues: #282, #316, #344, #387, #409.

Fix

Always insert bundled LSP infrastructure paths at the front of sys.path, regardless of import strategy. The user's environment should only affect resolution of isort itself, never the LSP server infrastructure.

Changes needed in 3 files:

1. bundled/tool/lsp_server.py

Remove the existing update_sys_path function and the two calls to it (lines 17–36):

def update_sys_path(path_to_add: str, strategy: str) -> None:
    """Add given path to `sys.path`."""
    if path_to_add not in sys.path and os.path.isdir(path_to_add):
        if strategy == "useBundled":
            sys.path.insert(0, path_to_add)
        elif strategy == "fromEnvironment":
            sys.path.append(path_to_add)


# Ensure that we can import LSP libraries, and other bundled libraries.
update_sys_path(
    os.fspath(pathlib.Path(__file__).parent.parent / "libs"),
    os.getenv("LS_IMPORT_STRATEGY", "useBundled"),
)

# https://github.com/microsoft/vscode-isort/issues/316#issuecomment-2103588949
update_sys_path(os.fspath(pathlib.Path(__file__).parent.parent / "tool"), "useBundled")

Replace with:

# **********************************************************
# Update sys.path before importing any bundled libraries.
# Always insert bundled paths first so user-installed packages
# never shadow LSP infrastructure (pygls, lsprotocol, etc.).
# **********************************************************
_bundled_libs = os.fspath(pathlib.Path(__file__).parent.parent / "libs")
if _bundled_libs not in sys.path and os.path.isdir(_bundled_libs):
    sys.path.insert(0, _bundled_libs)

_bundled_tool = os.fspath(pathlib.Path(__file__).parent)
if _bundled_tool not in sys.path and os.path.isdir(_bundled_tool):
    sys.path.insert(0, _bundled_tool)

2. bundled/tool/lsp_runner.py

Remove the update_sys_path function and its call (lines 16–29):

def update_sys_path(path_to_add: str, strategy: str) -> None:
    """Add given path to `sys.path`."""
    if path_to_add not in sys.path and os.path.isdir(path_to_add):
        if strategy == "useBundled":
            sys.path.insert(0, path_to_add)
        else:
            sys.path.append(path_to_add)


# Ensure that we can import LSP libraries, and other bundled libraries.
update_sys_path(
    os.fspath(pathlib.Path(__file__).parent.parent / "libs"),
    os.getenv("LS_IMPORT_STRATEGY", "useBundled"),
)

Replace with:

# Always prioritize bundled LSP infrastructure
_bundled_libs = os.fspath(pathlib.Path(__file__).parent.parent / "libs")
if _bundled_libs not in sys.path and os.path.isdir(_bundled_libs):
    sys.path.insert(0, _bundled_libs)

3. bundled/tool/lsp_utils.py

Change line 161 from:

    with contextlib.suppress(SystemExit):

To:

    with contextlib.suppress(SystemExit, ImportError):

This ensures that if a broken import still slips through despite the sys.path fix, _run_module degrades gracefully instead of propagating the exception up to crash the server.

Important notes

  • Do NOT change any other logic in these files
  • Do NOT add any new decorator or handler wrapping
  • Do NOT modify script_runner.py or _debug_server.py
  • The update_sys_path function is also used in script_runner.py and _debug_server.py but those have their own copies — leave those untouched
  • Make sure existing tests still pass

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Running "pip install -r requirements.txt" Makes the server crash. Are there any issues describing this?

Assistant: I searched the microsoft/vscode-isort repository for issues related to running pip install -r requirements.txt causing the server to crash. There are no issues that specifically describe running pip install -r requirements.txt as causing the isort server to crash.

However, there are many closed issues about the isort server crashing due to dependency/environment conflicts — which is the likely root cause of what you're experiencing. When you run pip install -r requirements.txt, packages installed into the Python environment can conflict with the extension's bundled dependencies, causing the LSP server to fail. Here are the most relevant ones:

data:
- url: "https://github.com/microsoft/vscode-isort/issues/282"
  repository: "microsoft/vscode-isort"
  state: "closed"
  draft: false
  title: "`typeguard` incompatibility: \"The isort server crashed 5 tim...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

- lsp_server.py: Replace update_sys_path with unconditional insert(0,...) for bundled libs and tool dirs
- lsp_runner.py: Replace update_sys_path with unconditional insert(0,...) for bundled libs
- lsp_utils.py: Add ImportError to contextlib.suppress in _run_module for graceful degradation

Fixes: #282, #316, #344, #387, #409

Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix sys.path ordering for bundled LSP infrastructure Fix bundled LSP paths always inserted at front of sys.path regardless of importStrategy Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants