[BUG] Python extension's venv activation is typed into Claude's prompt input instead of a shell

Status Open
Reported on v2.1.252
Maintainer reply None cached
Activity 0 comments · opened Sep 8, 2026

Refiling per the stale-close instruction on #80657 ("Please open a new issue if this is still relevant"). It is still relevant, it still reproduces on current versions, and I have a repro that does not depend on any user shell configuration — which I think is why the original report was easy to set aside.

Summary

With claudeCode.useTerminal: true, the Claude Code extension launches claude in a VS Code integrated terminal. Independently, the Python extension (ms-python.python) with python.terminal.activateEnvironment: true — its default — calls terminal.sendText() on newly created terminals to activate the workspace's selected interpreter. In a workspace with a .venv, that text is source /path/to/project/.venv/bin/activate.

The two race, and Claude Code loses. By the time the Python extension sends its activation text, claude already owns the TTY, so the bytes are read by the TUI's stdin handler and rendered into the prompt buffer instead of being executed by a shell. The result is the worst of both outcomes:

  • The venv is never activated — the command never reaches a shell.
  • Every new Claude window opens with source /Users/<me>/<project>/.venv/bin/activate sitting unsent in the input box, cursor at the end, to be backspaced away before the session can be used.

Both extensions are at stock defaults. No shell rc file is involved.

Repro

  1. macOS, VS Code, a Python project containing a .venv.
  2. Select the .venv interpreter for the workspace. Leave python.terminal.activateEnvironment at its default (true).
  3. Set claudeCode.useTerminal: true.
  4. Open a new Claude Code window in that workspace. The message input is pre-filled with the activation command.
  5. Set claudeCode.useTerminal: false and reload the window. The input comes up empty.

Step 5 is the control, and it confirms the mechanism: with no terminal, the Python extension has nothing to sendText into, and the pollution disappears entirely.

Expected

The input box starts empty. Anything arriving on stdin before the TUI is ready for typed input should be discarded rather than rendered into the prompt.

Workarounds, both with a cost

python.terminal.activateEnvironment: false at workspace level stops it, but also disables activation in ordinary integrated terminals in that workspace, where sendText works correctly and is genuinely wanted.

claudeCode.useTerminal: false also stops it, and is the better fix in isolation, but costs the status line — context-window and cost visibility are not exposed in the native UI (#92853).

Suggested direction

The general fix is on the Claude Code side: drain or ignore stdin received before the TUI is interactive. That covers this case, the ~/.zshenv variant in #80657, and any other extension or shell hook that writes to the terminal at startup.

There is also a narrower interaction worth fixing regardless, which I filed separately as #92887: claudeCode.usePythonEnvironment (default true) is only honored on the SDK spawn path used by the native UI, and silently no-ops under useTerminal: true. I verified that by reading the extension bundle and by A/B-ing the claude process environment across both modes. If the terminal path contributed the environment the same way — via EnvironmentVariableCollection, which sets variables without writing to the terminal — the venv would actually be activated and the Python extension's sendText would be redundant here rather than harmful.

Taken together the two defects compound: terminal mode disables the activation mechanism that works, and exposes the one that doesn't.

Environment

  • Claude Code CLI 2.1.252, VS Code extension 2.1.263 (darwin-arm64)
  • ms-python.python 2026.4.0
  • macOS 26.6.2 (Apple silicon), zsh
  • Reproduces consistently on every new Claude window in the affected workspace

Related

  • #80657 — the original report, closed as stale with an instruction to refile. Additional process-level detail is in https://github.com/anthropics/claude-code/issues/80657#issuecomment-5586877297.
  • #92887 — usePythonEnvironment no-op under useTerminal, same trigger.
  • microsoft/vscode-python#25744 — same root class from the extension side (activation text leaking into stdin of a process that already owns the TTY), scoped to tasks on Windows.

View original on GitHub ↗