Skip to content

Fix Git Bash conda activation when conda init bash was run (#1370)#1609

Merged
dmitrivMS merged 1 commit into
microsoft:mainfrom
StellaHuang95:fix/gitbash-conda-already-initialized
Jun 25, 2026
Merged

Fix Git Bash conda activation when conda init bash was run (#1370)#1609
dmitrivMS merged 1 commit into
microsoft:mainfrom
StellaHuang95:fix/gitbash-conda-already-initialized

Conversation

@StellaHuang95

@StellaHuang95 StellaHuang95 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Closes #1370

Context

On Windows, when a user has run conda init bash and has auto_activate_base enabled (conda default), opening a Git Bash terminal in VS Code with auto-activation enabled causes every subsequent conda command to fail with:

bash: /cygdrive/c/Users/<user>/anaconda3/Scripts/conda.exe: No such file or directory

The terminal still displays (base) and appears active, but conda is silently broken until the user closes and reopens the terminal.

Root cause

A chain of three independent systems creates the failure:

  1. The user's ~/.bashrc (modified by conda init bash) initializes conda on shell startup — defines the conda shell function and sets CONDA_EXE correctly.
  2. auto_activate_base = true activates (base), which prepends anaconda3/Library/usr/bin to PATH. That directory ships Anaconda's own (Cygwin-style) cygpath, which now shadows Git Bash's MSYS cygpath. The two emit different path formats:
    • Git Bash's cygpath C:\foo/c/foo ✅ (Git Bash understands)
    • Anaconda's cygpath C:\foo/cygdrive/c/foo ❌ (Git Bash does NOT understand)
  3. The extension then injects:
    source <conda>/etc/profile.d/conda.sh && conda activate <env>
    The first line of conda.sh is:
    export CONDA_EXE="$(cygpath 'C:/.../conda.exe')"
    Re-sourcing now runs the shadowed Cygwin cygpath, producing /cygdrive/c/.... CONDA_EXE is corrupted. The conda shell function (which delegates to $CONDA_EXE) fails for every subsequent invocation.

The corruption is entirely caused by re-sourcing conda.sh in a terminal that already initialized conda. If we skip the re-sourcing, the original (correct) CONDA_EXE remains intact and conda keeps working.

Why the existing safeguards do not catch this

buildShellActivationMapForConda has a P1 short-circuit that skips re-sourcing when isActiveOnLaunch is true. That flag is derived from process.env.CONDA_SHLVL at VS Code startup. The user launches VS Code normally (not from a conda-active shell), so CONDA_SHLVL is unset at the VS Code process level and the safeguard never fires — even though conda will be active inside every new terminal.

The extension already has a separate signal that does fire in this scenario: checkCondaInitInShellProfiles() reads the user's shell profiles and reports shellInitStatus.bash = true when conda initialize is present. The non-Windows path already accepts this signal, but only uses it as a fallback when sourcing scripts are missing. The Windows path doesn't accept it at all.

The fix

Pass shellInitStatus through to windowsExceptionGenerateConfig and add an early branch in the Git Bash logic:

if (shellInitStatus?.bash) {
    // .bashrc/.bash_profile already defines `conda` and sets CONDA_EXE
    // correctly. Re-sourcing conda.sh here would corrupt CONDA_EXE on
    // Windows when base is active (#1370).
    bashActivate = [{ executable: 'conda', args: ['activate', quotedPrefix] }];
}

The new branch is the first condition checked. When the user has run conda init bash, we emit only conda activate <prefix> instead of source conda.sh && conda activate <prefix>.

Why this fixes the issue

The bug is triggered by re-running cygpath (in a shadowed PATH context) inside conda.sh. By skipping the redundant source, we never re-execute that line, so CONDA_EXE retains the correct value set by the original conda init bash hook in the user's shell profile. The conda activate call then uses the already-loaded conda shell function with the correct CONDA_EXE, and everything works.

…s detected (microsoft#1370)

When a user on Windows has run `conda init bash` and has `auto_activate_base = true`,
re-sourcing `conda.sh` at terminal startup corrupts `CONDA_EXE`. The full Anaconda
distribution ships its own Cygwin-style `cygpath` in `Library/usr/bin`, which gets
prepended to PATH by base activation and shadows Git Bash's MSYS `cygpath`.
`conda.sh`'s first line re-runs `cygpath` and emits a `/cygdrive/c/...` path,
which Git Bash cannot resolve, so every subsequent `conda` command fails with
`bash: /cygdrive/c/.../conda.exe: No such file or directory`.

When `shellInitStatus.bash === true` (conda init detected in the user's
.bash_profile/.bashrc), the `conda` shell function and `CONDA_EXE` are already
loaded correctly when the terminal starts, so skip `source conda.sh` and emit
only `conda activate <prefix>`.

- Add optional `shellInitStatus` parameter to `windowsExceptionGenerateConfig`.
- Pass `envManager.sourcingInformation.shellInitStatus` from caller (mirrors
  what the non-Windows path already does).
- Tests cover bash=true skips source, bash=false / undefined preserve existing
  behavior, prefix quoting still works, and PowerShell/CMD activation unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eleanorjboyd eleanorjboyd added the bug Issue identified by VS Code Team member as probable bug label Jun 25, 2026
@dmitrivMS dmitrivMS merged commit 5d919c1 into microsoft:main Jun 25, 2026
45 of 46 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.

environment auto-activation fails on conda-inited shell [moved/copied]

3 participants