Change:
}); }); }); <ins> suite('createTerminalEnvironment', () => { const commonVariables = { COLORTERM: 'truecolor', TERM_PROGRAM: 'vscode' }; test('should retain variables equal to the empty string', async () => { deepStrictEqual( await createTerminalEnvironment({}, undefined, undefined, undefined, 'off', { foo: 'bar', empty: '' }), { foo: 'bar', empty: '', ...commonVariables } ); }); }); </ins> });

Discussion:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.75.1 (Universal) OS Version: macOS 13.2 When VS Code is launched with a set but empty env var, it will drop it and treat it as unset. This breaks workflows which check for the presence of env vars (which may be empty in some cases) when running VS Code integrations, e.g. running tests, running the debugger. Steps to Reproduce: vscode using command with a terminal within vscode run: , and then that is missing, is set Compare with running in a terminal manually, with an empty : Of the available historical downloads, I found that vscode 1.73.1 still replicates the above, but does seem to correctly pass the empty env vars down to other processes (e.g. the debugger).
I'm seeing the variable make it to the debugger, eg here in the debug console, it's in <img width="133" alt="image" src="https://user-"But I'm not seeing it in the terminal. does one of the terminal processes clear out variables with empty values?
yep, looks like that would happen here
To give some more context on how I was experiencing the issue primarily: it was when running tests or the debugger (with the Go extension installed). Is it possible a similar (or maybe the same) behaviour to is affecting how env vars get passed down to extensions (as well as the terminal process)?
Maybe if the debuggee is launched from a terminal? Or something particular to that debug extension. It worked for me when debugging node.

I did think it could be one of those at first, but I can reliably repro the issue in latest VS Code, whilst 1.73.1 works fine with the same setup (although still reproduces the integrated terminal bug). When I get a moment, I'll put together a minimal repro for the extension issue just so it is testable.
I just tested out the insider build with this fix and it looks like the terminal itself now has the environment variables set correctly. But other areas, like the test runners, don't. For example I tried running a golang test using the play button in the gutter and the tests still failed with an error about an environment variable not being set. As mentioned, this worked fine in 1.73.1.
thanks, maybe we have a similar check for terminals created via extensions. Will have a look
This is working fine for me. To verify: Test to ensure a variable in with a value of comes through to the actual terminal environment Do the same when the environment change is applied via the extension API
I'm still seeing the issue in the current insider build. I've created a minimal reproduction of the issue. a new go project a new go file with the following content another new go file with the following content the project using to and run the test test will fail on line 15 with the error "FOO not set" As mentioned above this works properly in version 1.73.1 and the test passes
should I file a new issue for the scenario I described above or will this issue be reopened to look into it?
I think it's tracked in