-
Notifications
You must be signed in to change notification settings - Fork 95
Description
Bug: registerNoConfigDebug corrupts terminal PATH by missing semicolon separator on Windows
Environment
- OS: Windows 11 Pro
- VS Code: latest stable
ms-python.debugpyextension version: 2025.18.0- Other relevant extensions:
ms-dotnettools.vscode-dotnet-runtime3.0.0
Description
The registerNoConfigDebug function appends the noConfigScripts directory to the terminal PATH via EnvironmentVariableCollection.append(), but it decides whether to prepend a ; separator by checking process.env.PATH in the extension host process rather than the terminal's actual PATH. When process.env.PATH in the extension host ends with ; (e.g. because another extension like ms-dotnettools.vscode-dotnet-runtime modifies it directly via process.env.PATH += delimiter + path), the separator is omitted, corrupting the terminal PATH.
Steps to Reproduce
- Install
ms-python.debugpyalongside an extension that directly mutatesprocess.env.PATHin the extension host (e.g.ms-dotnettools.vscode-dotnet-runtime). - Ensure the user
PATHcontains entries likeC:\Users\<user>\.local\binnear the end. - Open a new integrated terminal in VS Code.
- Run:
$env:Path -split ';' | Select-String '\.local\\bin'
Expected Behavior
C:\Users\<user>\.local\bin
Each PATH entry is properly separated by ;.
Actual Behavior
C:\Users\<user>\.local\binc:\Users\<user>\.vscode\extensions\ms-python.debugpy-2025.18.0-win32-x64\bundled\scripts\noConfigScripts
The two paths are concatenated without a ; separator, making both entries unresolvable. Any executable in .local\bin (e.g. claude) becomes unavailable in the VS Code terminal while working fine in a standalone terminal.
Root Cause
In src/extension/noConfigDebugger/noConfigDebugAdapter.ts (minified in dist/extension.js):
const noConfigPath = path.join(extensionPath, "bundled", "scripts", "noConfigScripts");
const delimiter = process.platform === "win32" ? ";" : ":";
const currentPath = process.env.PATH || "";
const value = currentPath.length > 0 && !currentPath.endsWith(delimiter)
? `${delimiter}${noConfigPath}`
: noConfigPath;
collection.append("PATH", value);The issue is that process.env.PATH reflects the extension host process environment, which can be modified by other extensions at runtime (e.g. process.env.PATH += ";" + somePath). However, EnvironmentVariableCollection.append() operates on the terminal environment, which is constructed independently by VS Code from the system/user PATH plus all extensions' EnvironmentVariableCollection mutations.
When the extension host's process.env.PATH happens to end with ; (due to another extension's direct mutation), the condition !currentPath.endsWith(delimiter) evaluates to false, so the delimiter is omitted. But the terminal's actual PATH does not end with ;, resulting in a corrupted concatenation.
Suggested Fix
Always prepend the delimiter when appending, since EnvironmentVariableCollection.append() performs raw string concatenation:
const value = `${delimiter}${noConfigPath}`;
collection.append("PATH", value);This is safe even if the terminal PATH already ends with ; — it would just produce an empty entry (;;), which is harmless and is the standard defensive practice for PATH manipulation.