Repository navigation
[Bug]: Linux AppImage env (ARGV0, ELECTRON_RUN_AS_NODE) still leaks into provider agent sessions #16456
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- On Linux, launch the T3 Code AppImage. The user's login shell is zsh.
- Start a Codex thread and ask the agent to run:
env | grep -E '^(ARGV0|APPIMAGE|APPDIR|OWD|ELECTRON_RUN_AS_NODE)=' python3 -c 'import sys; print(sys.executable)'
- Optional, to see the failure it causes. Ask the agent to run:
d=$(mktemp -d) python3 -c "import sys; open('$d/s','w').write('#!'+sys.executable+'\nimport json,os\nprint(1)\n')" chmod +x "$d/s" && "$d/s"
The leak also shows on the host, outside any agent: tr '\0' '\n' < /proc/<pid>/environ for the T3 server process (t3code --require …/app.asar…) and for each provider process it spawns (claude …).
Expected behavior
Provider sessions get the host environment, the same way the integrated terminal does since #3108. ARGV0, APPIMAGE, APPDIR, OWD and ELECTRON_RUN_AS_NODE are not set, and PATH/LD_LIBRARY_PATH have no /tmp/[.mount_T3-*](https://github.com/tmp/.mount_T3-*) entries. sys.executable is /usr/bin/[python3](https://github.com/usr/bin/python3).
Actual behavior
#3108 strips the AppImage runtime env in apps/server/src/terminal/[Manager.ts](https://github.com/home/eduardo/.t3/scratch/2026-10-06-retro-lets-run-it-on-9c849431/apps/server/src/terminal/Manager.ts), but only for terminal sessions. Provider sessions still inherit the server's environment unchanged:
ARGV0,APPIMAGE,APPDIRandOWDare set,PATHhas/tmp/[.mount_T3-*](https://github.com/tmp/.mount_T3-*)and/tmp/.mount_T3-*/usr/[sbin](https://github.com/tmp/.mount_T3-*/usr/sbin), and the server hasLD_LIBRARY_PATH=/tmp/.mount_T3-*/usr/lib.ELECTRON_RUN_AS_NODE=1is set as well.
Codex runs commands through the user's login shell. zsh uses an exported ARGV0 as argv[0] for every external command it starts, the same way as in #2509. So every program the agent runs gets the AppImage path as argv[0]. Python derives sys.executable from argv[0], so sys.executable is the AppImage. Because ELECTRON_RUN_AS_NODE=1 is set too, anything that execs sys.executable runs Node, not Python. The step 3 script fails with a JavaScript SyntaxError.
We hit this in a project's test suite: a test fixture wrote a #!{sys.executable} shim, and under a Codex agent in T3 the test failed with the error below. The same suite passes in a normal terminal. Every delegated Codex agent hit it again until we added a workaround.
Shell check of the mechanism, outside T3:
env ARGV0=/path/to/T3.AppImage zsh -c "python3 -c 'import sys; print(sys.executable)'" # /path/to/T3.AppImage
env ARGV0=/path/to/T3.AppImage bash -c "python3 -c 'import sys; print(sys.executable)'" # /usr/bin/python3Suggested fix: apply the #3108 environment sanitizer to provider and agent process spawns too, and remove ELECTRON_RUN_AS_NODE there.
Impact
Minor bug or occasional failure
Version or commit
0.0.46-nightly.20261004.2652 (first seen). Still present in 0.0.46-nightly.20261005.2702.
Environment
Fedora 44, kernel 7.2.8, T3 Code Linux AppImage, zsh 5.9, Python 3.14.7. Codex CLI 0.160.0. The Claude provider process has the same variables.
Logs or stack traces
# inside the Codex agent shell
$ python3 -c 'import sys; print(sys.executable)'
/home/<user>/Downloads/T3-Code-0.0.46-nightly.20261004.2652-x86_64.AppImage
$ env | grep -E '^(ELECTRON|PATH)'
ELECTRON_RUN_AS_NODE=1
PATH=…:/tmp/.mount_T3-CodffXPwV:/tmp/.mount_T3-CodffXPwV/usr/sbin:/usr/local/bin:/usr/bin:/bin
# test fixture that execs a '#!{sys.executable}' script
file:///tmp/fedora%20review%20fixes%209w3635e1/bin/python3:2
import json,os,pathlib,sys
^
SyntaxError: Unexpected token ','
at compileSourceTextModule (node:internal/modules/esm/utils:320:16)
at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:89:18)Screenshots, recordings, or supporting files
No response
Workaround
Run commands with env -u ELECTRON_RUN_AS_NODE, or resolve the interpreter with shutil.which('python3') instead of sys.executable. Neither fixes argv[0] for other programs.
Activity
juliusmarminge commentedon Oct 6, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks @dubonzi for tracking this down so precisely, the zsh
ARGV0detail made it easy to follow. Reading currentmain, this looks like the provider-session half of the AppImage leak that #1699, #2509, and #5059 addressed for integrated terminals only.What I found
stripAppImageRuntimeEnvinapps/server/src/terminal/Manager.ts) is scoped tocreateTerminalSpawnEnv, so agent CLIs stay on the server's environment.extendEnv: trueandELECTRON_RUN_AS_NODE=1(apps/desktop/src/backend/DesktopBackendConfiguration.ts). That part is needed, since the packaged server runs as Electron-as-Node, so the server process itself showingAPPIMAGE,APPDIR,ARGV0,OWD, andELECTRON_RUN_AS_NODEis expected.HostProcessEnvironmentisprocess.env,mergeProviderInstanceEnvironmentspreads it, and both providers hand the result to the child:CodexAdapterV2.layerAppServerClientFactory) spawnscodexwith that object asenv.createClaudeAdapterV2→makeClaudeEnvironment) only overlaysCLAUDE_CONFIG_DIRand passes the rest to the Agent SDK.ARGV0/APPIMAGE/APPDIR/OWD, drops/tmp/.mount_T3-*segments fromPATH,LD_LIBRARY_PATH,XDG_DATA_DIRS, orGSETTINGS_SCHEMA_DIR, or removesELECTRON_RUN_AS_NODE. The terminal path does both (stripAppImageRuntimeEnv, plusELECTRON_RUN_AS_NODEonTERMINAL_ENV_BLOCKLIST).ARGV0asargv[0]for external commands (same mechanism as [Bug]: Ubuntu 26.04 - AppImageARGV0leak corruptszshintegrated terminal - causescoreutilscrashes #2509), Python setssys.executablefrom it, and withELECTRON_RUN_AS_NODE=1still set the re-exec'd AppImage runs as Node. Bash doesn't do theARGV0rewrite.Likely fix area
One option is to reuse the terminal scrub on the environment that provider agents and their shells inherit, rather than on the server process itself. A few places set
ELECTRON_RUN_AS_NODEdeliberately, which may matter for how broadly it's removed:ELECTRON_RUN_AS_NODEand sets it back to"1"so its browser helper can run the packaged binary as Node (antigravityEnvironmentinapps/server/src/provider/antigravityAuthSupport.ts). It still copiesARGV0/APPIMAGEfrom the base env.ELECTRON_RUN_AS_NODE=1only on thet3 acp-mcp-bridgeserver entry (AcpAdapterV2).execof the agent (wrapCommandForLinuxCgroup), but that doesn't remove the other AppImage variables, and Codex and Claude don't go through that wrapper.A maintainer will decide on the fix direction.
Jord-JD commentedon Oct 16, 2026
One more path leaks
ELECTRON_RUN_AS_NODE=1, and it isn't covered by the terminal fix onmainor by #16679: the server's external launcher, which opens browsers, editors and the file manager.launchAndUnrefinapps/server/src/process/externalLauncher.tsspawnsxdg-open(or an editor) with the server's full environment. A file manager opened that way passesELECTRON_RUN_AS_NODE=1to everything started from it. For example, Open in file manager → Dolphin → open a Konsole there.Repro on Linux (desktop app):
env | grep ELECTRON_RUN_AS_NODE. It printsELECTRON_RUN_AS_NODE=1.Workaround:
env -u ELECTRON_RUN_AS_NODE ./my-electron-app.AppImage.The desktop main process doesn't have the variable. The backend process does, because it is launched with it on purpose, and every child it spawns inherits it. That includes agent sessions (covered by #16679) and launched apps. VS Code handles this by deleting
ELECTRON_RUN_AS_NODEfrom the environment of what it launches (sanitizeProcessEnvironmentinsrc/vs/base/common/processes.tsandsrc/vs/code/node/cli.ts).I'll open a small PR that only covers the external launcher, so it doesn't overlap with #16679.