Environment
|
|
| Extension |
ms-python.vscode-python-envs 1.36.0 (also present in 1.37.2026090401, published 2026-09-04) |
| VS Code |
1.137.0 |
| OS |
macOS 15.6 (arm64) |
| Shell |
zsh |
| Environment manager |
uv (plus ms-python.python:system for comparison) |
Steps to reproduce
uv python install 3.13 — installs a toolchain to ~/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/.
- Open a folder in VS Code whose selected interpreter is that toolchain:
Ctrl/Cmd+Shift+P → Python: Select Interpreter → Enter interpreter path… →
~/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/python
- Open an integrated terminal.
Actual behavior
source /Users/<user>/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/activate
source: no such file or directory: /Users/<user>/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/activate
The toolchain's bin/ contains python3.13, python, pip, idle3 — there is no activate.
A uv python install toolchain is a base interpreter, not a virtual environment, so the failure
is not a broken install: the activation command itself should never have been emitted.
Once persisted, the same command is emitted on every new terminal in that folder and
survives restarts — this is not a one-off.
Python Environments log for the same window:
[interpreterSelection] deven367: cpython-3.13.9-macos-aarch64-none (3.13.9) (source: autoDiscovery)
Terminal is activated: /Users/<user>/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/python
(The extension also auto-discovered and selected this toolchain for a folder with no
environment at all, with no user selection — same outcome.)
Expected behavior
No activation command is emitted for an environment that cannot be activated; either the
toolchain is reported as non-activatable (like system environments, which correctly emit
nothing), or the activation command is gated on the activation script existing.
Cause
getShellActivationCommands(dir) sets the sh/bash/zsh/gitbash (and "unknown") activation
entries unconditionally, while fish/csh/xsh/nu are gated on pathExists:
t.getShellActivationCommands = async function (e) {
const t = new Map(), n = new Map();
return isWindows()
? t.set("unknown", [{ executable: join(e, "activate") }])
: t.set("unknown", [{ executable: "source", args: [join(e, "activate")] }]), // no pathExists
t.set(SH, [{ executable: "source", args: [join(e, "activate")] }]), // no pathExists
t.set(BASH, [{ executable: "source", args: [join(e, "activate")] }]), // no pathExists
t.set(GITBASH, [{ executable: "source", args: [v(join(e, "activate"))] }]), // no pathExists
t.set(ZSH, [{ executable: "source", args: [join(e, "activate")] }]), // no pathExists
...
await pathExists(join(e, "activate.csh")) && t.set(CSH, ...); // gated
await pathExists(join(e, "activate.fish")) && t.set(FISH, ...); // gated
await pathExists(join(e, "activate.xsh")) && t.set(XSH, ...); // gated
await pathExists(join(e, "activate.nu")) && t.set(NU, ...); // gated
return { shellActivation: t, shellDeactivation: n };
};
It is called with dirname(executable), i.e. <prefix>/bin:
const a = dirname(e.executable),
{ shellActivation: o, shellDeactivation: s } = await getShellActivationCommands(a);
So for any prefix without bin/activate, a failing command is produced instead of an
environment with no activation. isActivatableEnvironment() then returns true, because it
only checks that shellActivation is non-empty:
t.isActivatableEnvironment = function (e) {
return !!e.execInfo?.activation || !!e.execInfo?.shellActivation;
};
The uv manager registers these toolchains through the venv path — the log shows
Found venv environment: cpython-3.13.9-macos-aarch64-none (3.13.9) for a directory that has
no pyvenv.cfg and no activate. system environments, which carry no shellActivation,
behave correctly and emit nothing.
Suggested fix
- Gate the sh/bash/zsh/gitbash/unknown entries on
pathExists(join(dir, "activate")), matching
the existing fish/csh/xsh/nu checks, so a prefix without an activation script yields an
effectively non-activatable environment.
- Optionally, additionally report
uv python install toolchains as non-activatable (they have
no pyvenv.cfg), so they are not offered as activatable venv environments.
Workaround
Pin the folder to the system manager, which emits no activation command:
"python-envs.pythonProjects": [
{ "path": "<folder>", "envManager": "ms-python.python:system" }
]
or select a real .venv / system interpreter instead of the uv toolchain.
Additional context
Reproduced by selecting the interpreter through Python: Select Interpreter → Enter interpreter
path… in the GUI, and independently by restoring the persisted
ms-python.vscode-python-envs:venv:WORKSPACE_SELECTED entry the picker writes.
Unrelated observation from the same session, in case it is useful: activating the extension
wrote "python-envs.defaultEnvManager": "ms-python.python:venv" into the workspace
settings.json (~/.vscode/settings.json) by itself.
Environment
ms-python.vscode-python-envs1.36.0 (also present in 1.37.2026090401, published 2026-09-04)uv(plusms-python.python:systemfor comparison)Steps to reproduce
uv python install 3.13— installs a toolchain to~/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/.Ctrl/Cmd+Shift+P→ Python: Select Interpreter → Enter interpreter path… →~/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/pythonActual behavior
The toolchain's
bin/containspython3.13,python,pip,idle3— there is noactivate.A
uv python installtoolchain is a base interpreter, not a virtual environment, so the failureis not a broken install: the activation command itself should never have been emitted.
Once persisted, the same command is emitted on every new terminal in that folder and
survives restarts — this is not a one-off.
Python Environments log for the same window:
(The extension also auto-discovered and selected this toolchain for a folder with no
environment at all, with no user selection — same outcome.)
Expected behavior
No activation command is emitted for an environment that cannot be activated; either the
toolchain is reported as non-activatable (like
systemenvironments, which correctly emitnothing), or the activation command is gated on the activation script existing.
Cause
getShellActivationCommands(dir)sets the sh/bash/zsh/gitbash (and "unknown") activationentries unconditionally, while fish/csh/xsh/nu are gated on
pathExists:It is called with
dirname(executable), i.e.<prefix>/bin:So for any prefix without
bin/activate, a failing command is produced instead of anenvironment with no activation.
isActivatableEnvironment()then returnstrue, because itonly checks that
shellActivationis non-empty:The uv manager registers these toolchains through the venv path — the log shows
Found venv environment: cpython-3.13.9-macos-aarch64-none (3.13.9)for a directory that hasno
pyvenv.cfgand noactivate.systemenvironments, which carry noshellActivation,behave correctly and emit nothing.
Suggested fix
pathExists(join(dir, "activate")), matchingthe existing fish/csh/xsh/nu checks, so a prefix without an activation script yields an
effectively non-activatable environment.
uv python installtoolchains as non-activatable (they haveno
pyvenv.cfg), so they are not offered as activatable venv environments.Workaround
Pin the folder to the system manager, which emits no activation command:
or select a real
.venv/ system interpreter instead of the uv toolchain.Additional context
Reproduced by selecting the interpreter through Python: Select Interpreter → Enter interpreter
path… in the GUI, and independently by restoring the persisted
ms-python.vscode-python-envs:venv:WORKSPACE_SELECTEDentry the picker writes.Unrelated observation from the same session, in case it is useful: activating the extension
wrote
"python-envs.defaultEnvManager": "ms-python.python:venv"into the workspacesettings.json(~/.vscode/settings.json) by itself.