Skip to content

Fix base conda environment incorrectly resolved to a named environment on reload#1412

Merged
eleanorjboyd merged 2 commits intomicrosoft:mainfrom
StellaHuang95:fixBug
Mar 30, 2026
Merged

Fix base conda environment incorrectly resolved to a named environment on reload#1412
eleanorjboyd merged 2 commits intomicrosoft:mainfrom
StellaHuang95:fixBug

Conversation

@StellaHuang95
Copy link
Copy Markdown
Contributor

Fixes microsoft/vscode-python#25814

Problem

After selecting the base conda environment and reloading VS Code, a different named conda environment is shown as active instead. The wrong environment is typically whichever named env has the highest Python version.

Root Cause

findEnvironmentByPath() in CondaEnvManager uses a single Array.find() with three match strategies evaluated in OR: exact path, parent directory, and grandparent directory.

// Before (broken)
return this.collection.find((e) => {
    const n = normalizePath(e.environmentPath.fsPath);
    return (
        n === normalized ||
        normalizePath(path.dirname(e.environmentPath.fsPath)) === normalized ||
        normalizePath(path.dirname(path.dirname(e.environmentPath.fsPath))) === normalized
    );
});

Conda environments have this disk layout:

/miniconda3/                    ← base environment (prefix)
/miniconda3/envs/torch/         ← named env "torch"
/miniconda3/envs/data_science/  ← named env "data_science"

The grandparent of every named environment (dirname(dirname(/miniconda3/envs/torch))) equals the base environment's own path (/miniconda3). Since the collection is sorted by Python version descending, any named env with a higher version than base appears before base in the array. Array.find() returns the first match — so the named env matches via grandparent before base can match via exact path.

This only triggers on reload/restart (not live selection), because loadEnvMap() reads the stored path from persistent state and calls findEnvironmentByPath() to resolve it back to an environment object.

Fix

Split the single find() into two passes — exact match first, then parent/grandparent fallback:

// After (fixed)
const exact = this.collection.find((e) => normalizePath(e.environmentPath.fsPath) === normalized);
if (exact) {
    return exact;
}
return this.collection.find((e) => {
    return (
        normalizePath(path.dirname(e.environmentPath.fsPath)) === normalized ||
        normalizePath(path.dirname(path.dirname(e.environmentPath.fsPath))) === normalized
    );
});

This ensures base's prefix /miniconda3 always matches itself exactly before any named env can match via grandparent. The parent/grandparent fallback is preserved for cases where a binary path (e.g. .../bin/python) needs resolving.

Testing

Added 17 unit tests covering:

  • Core bug scenario (base with lower version vs named envs with higher versions)
  • Exact match priority over parent/grandparent matches
  • Standard exact, parent, and grandparent matching
  • Empty collection and no-match cases
  • Windows backslash paths
  • Deeply nested paths that shouldn't match

@eleanorjboyd eleanorjboyd merged commit ac36330 into microsoft:main Mar 30, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue identified by VS Code Team member as probable bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot switch to base conda environment in interactive window after latest updates

2 participants