WSL task shells inherit Windows TEMP/TMP and ignore login profiles
What version of Codex is running?
codex-cli 0.149.0-alpha.4.3, launched by ChatGPT Desktop on Windows into WSL2.
What happened?
Local shell commands inside a WSL task inherit Windows TEMP and TMP through the process-scoped WSLENV. Python therefore chooses a mounted Windows path such as /mnt/c/Users/<user>/AppData/Local/Temp instead of /tmp.
This breaks Python temporary files on drvfs. A minimal example can read and write a TemporaryFile, but truncate() raises FileNotFoundError. Pytest then crashes in its capture cleanup before tests run.
The command executor also does not appear to load the WSL login profile even when login semantics are requested. Setting the variables in both ~/.profile and ~/.bashrc has no effect on ordinary task shell calls, while wrapping the same command in an explicit bash -lc immediately fixes it.
Steps to reproduce
- Start a local Codex task in WSL2 from ChatGPT Desktop on Windows.
- Run:
python -c 'import os,tempfile; print(os.environ.get("TEMP")); print(tempfile.gettempdir()); f=tempfile.TemporaryFile(); f.write(b"x"); f.seek(0); print(f.read()); f.truncate()'
Observed result:
/mnt/c/Users/<user>/AppData/Local/Temp
/mnt/c/Users/<user>/AppData/Local/Temp
b'x'
FileNotFoundError: [Errno 2] No such file or directory
- Add this to the Linux login profile:
export TMPDIR=/tmp
export TMP=/tmp
export TEMP=/tmp
- Run the original command through the task executor again. It still sees the Windows values.
- Run it as
bash -lc '<original command>'. It sees/tmpand completes.
Expected behavior
For WSL tasks, Codex should default temporary-file variables to a Linux path, or reliably honor the user's shell profile when the executor requests login semantics.
At minimum, the documented workaround should work consistently:
[shell_environment_policy]
experimental_use_profile = true
[shell_environment_policy.set]
TMPDIR = "/tmp"
TMP = "/tmp"
TEMP = "/tmp"
Additional context
This is specific to the process environment passed by ChatGPT Desktop. User- and machine-scoped WSLENV values are empty, while the Desktop process adds TEMP/p:TMP/p before launching WSL.
The bundled Desktop runtimes and the Codex WSL bridge should remain available; the request is only to keep general WSL subprocess temporary files on the Linux filesystem.