Environment-variable leak between workspaces

Version: 0.49.6
VSCode Version: 1.96.2
Commit: 0781e811de386a0c5bcb07ceb259df8ff8246a50
Date: 2025-04-25T05:07:16.071Z
Electron: 34.3.4
Chromium: 132.0.6834.210
Node.js: 20.18.3
V8: 13.2.152.41-electron.0
OS: Darwin arm64 24.4.0


Summary

Opening a second workspace from an existing integrated‑terminal session causes the new workspace to inherit the first workspace’s .env variables via the Environment Variable Collection mechanism. This results in leaked secrets such as DB_PASSWORD across completely unrelated projects.

godotenv.Load() in Go cannot override the injected value, leading to confusing runtime failures.


Steps to reproduce

  1. Workspace B
    1. Create or open project B with this .env:
      # .env in B
      DB_PASSWORD=from-B
      
    2. Open a new integrated terminal (_⌃`` or Terminal > New Terminal).
    3. Before the “dotenv variables loaded” notification appears, run:
      echo $DB_PASSWORD   # ➜ (empty)
      
  2. Open Workspace A from the same terminal
    code ../A
    
    (or cursor ../A)
  3. Workspace A
    1. Verify that A either has no .env or a different one.
    2. Open a new integrated terminal in A and run:
      echo $DB_PASSWORD   # ➜ from-B   ← **bug**
      

Expected behaviour

  • Each workspace should receive only its own EnvironmentVariableCollection.
  • No variable from previously‑opened workspaces should be present by default.

Actual behaviour

  • The first workspace that parsed a .env file exports its keys to all subsequent workspaces opened from a terminal in that VS Code/Cursor process.
  • Terminals created in those later workspaces show the leaked variables.
  • Reloading the window clears the leak until another cross‑workspace open reproduces it.

Additional information & diagnostics

  • The leaked values are stored in SQLite cache files named state.vscdb under:
    ~/Library/Application Support/Cursor/User/workspaceStorage/<UUID>/state.vscdb
    
    (similar path for VS Code).
  • Setting
    "terminal.integrated.allowWorkspaceEnvironmentChanges": "never",
    "terminal.integrated.inheritEnv": false
    
    prevents the issue.
  • Removing inline comments from the affected .env lines does not stop the leak.

Possible root cause

The parent Electron process appears to keep a global cache of the last‑parsed EnvironmentVariableCollection. When code/cursor CLI attaches a second window, that cache is reused instead of being replaced with the new workspace’s collection. The terminal helper then applies whatever is cached to every terminal it spawns.


Workarounds

  • Relaunch the integrated terminal after switching workspaces.
  • Disable workspace environment contributions (settings above).
  • Use godotenv.Overload() or os.Unsetenv() in Go to override.

Suggested fix

Ensure that each EnvironmentVariableCollection is scoped per workspace window, not per Electron process, and that terminals inherit only the collection from the window they belong to.


Thank you! Please let me know if any further diagnostics (logs, full VS Code – Issue Reporter output, etc.) would be helpful.