You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cli: no way to refresh environment variables without restarting #48919
After modifying system/user environment variables (e.g., adding a new directory to PATH), OpenCode does not detect the changes until a full restart. There is no built-in way to refresh environment variables within a running session.
Environment
opencode version: 2.0.3
OS: Windows_NT 10.0.26200 (win32 x64)
Shell: Git Bash (MINGW64)
Reproduction
Install a CLI tool to a new directory (e.g., D:\Tools\gh\bin\)
Add the directory to the user PATH via system settings
In an active OpenCode session, try to use the tool: gh --version
Command not found — the new PATH is not reflected
Expected Behavior
OpenCode should either:
Re-read environment variables on demand (e.g., a refresh-env command or API)
Or detect PATH changes and update the shell environment automatically
Actual Behavior
The only workaround is to fully restart OpenCode. All running sessions, context, and state are lost.
Additional Context
This affects any workflow where tools are installed or environment variables are modified mid-session. Common scenarios:
Installing new CLI tools (gh, docker, etc.) via package managers
this isn't really opencode holding onto old values, a process gets its env when it starts and windows doesn't push PATH changes into processes that are already running. same reason the Git Bash window you had open won't see the new PATH either.
on 2.0.3 the cli snapshots its env at launch (Env.session() in packages/cli/src/env.ts) and the tui sends it to the session through session.environment when you open it, and the shell tool spawns with that. so you shouldn't lose anything by restarting, open a fresh terminal and run opencode --continue (or pick the session again) and the new PATH goes into that session. history is stored, it's not dropped on restart.
an actual in-app refresh would mean reading the user/system env out of the registry on windows and deciding how it merges with what the session already has, which seems like a design call for the team more than a quick PR.
I frequently need to configure proxy settings (HTTP_PROXY, HTTPS_PROXY, NO_PROXY, etc.) or other environment variables that should only apply to OpenCode — not to my entire system. For example:
Proxy configuration for API requests (providers, MCP servers)
Custom PATH entries for project-specific CLI tools
API keys or tokens scoped to a single project
What I think would help:
Config-level environment overrides — Allow setting environment variables in opencode.jsonc (global or project-level) that are applied to all sessions spawned by OpenCode. Something like:
TUI/Desktop env editor — A built-in UI (accessible via a shortcut or command) to view and edit environment variables for the current session or project, without needing to restart OpenCode.
Per-session env refresh — When starting a new session (not restarting OpenCode), re-read the current system environment and merge it with any config-level overrides. This way, even if the running OpenCode process has stale env vars, a fresh session picks up the latest.
This would solve the proxy use case cleanly: I set HTTP_PROXY in my project's opencode.jsonc, and every session in that project uses it for all outbound requests — regardless of what the host terminal's environment looks like.
Quick follow-up question: if I modify the system environment variables and then run opencode service restart, would the new sessions pick up the updated environment without losing existing session history? Or does the service also snapshot the env at its own launch time?
put up a draft for this anyway, it adds a windows-only /refresh-env command in the tui that reads the Machine and User variables from the registry through powershell and pushes them into the open session.
it only adds things: new PATH entries get appended and variables the session doesn't have get added, nothing existing gets replaced. that keeps the PATH entries Git Bash sets up for itself, but it also means an edited value like HTTP_PROXY won't change until restart. if overwriting non-PATH vars is preferred i can switch it. haven't been able to run it on windows myself, so it'd be good if someone could try it there.
yeah the service snapshots its env too. it gets spawned as a detached child of whichever opencode process starts it, with that process's env plus anything you set through opencode service set env (spawnServiceContender in packages/client/src/service-contender.ts). so opencode service restart run from a terminal you opened after changing the vars gives the service the new env, and history is fine since sessions are stored, not held by the service process. the cli restart does close persistent terminals though. the tui's /restart won't help here, that respawns the service from the tui process which still has the old env.
the catch is the shell tool. once the tui has pushed a session env it spawns with sessionEnvironment ?? process.env (packages/core/src/shell.ts), and an open tui re-pushes its own launch snapshot as soon as it reconnects. so a service restart updates what the service does itself, provider requests and mcp servers, but bash commands in a tui that was already open still get the old PATH. for those you need to reopen the tui from a new terminal, opencode --continue.
for the proxy case opencode service set env HTTP_PROXY http://127.0.0.1:7890 already exists and sticks across restarts, same caveat that it applies to the service process and not to shell commands in a tui session.
Thanks for the clear write-up! You're asking for a way to pick up changed environment variables (like a new PATH entry) in a running OpenCode session, without a restart. Right now OpenCode reads its environment once at startup, so this works as designed today. It's a reasonable improvement, though, and maintainers will consider it.
In the meantime, a plugin can cover the most common case: commands run by the shell tool (e.g. gh --version after editing PATH in System Settings). The plugin below re-reads your user and system environment from the Windows registry before every shell command. New Path entries go first, and any entries OpenCode already had are kept.
Save it as ~/.config/opencode/plugins/refresh-env.ts (or .opencode/plugins/refresh-env.ts in a project), then restart OpenCode once:
import{execFileSync}from"node:child_process"// Re-reads Windows user + system environment variables from the registry// before every shell command, so changes made in System Settings (e.g. a new// PATH entry) apply without restarting OpenCode.constKEYS=["HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment","HKCU\\Environment",]functionread(key: string){constvars: {name: string;type: string;value: string}[]=[]try{constout=execFileSync("reg",["query",key],{encoding: "utf8",windowsHide: true})for(constlineofout.split(/\r?\n/)){constm=line.match(/^\s{4}(\S.*?)\s{4}(REG_SZ|REG_EXPAND_SZ)\s{4}(.*)$/)if(m)vars.push({name: m[1],type: m[2],value: m[3]})}}catch{}returnvars}functionkeyOf(env: Record<string,string|undefined>,name: string){returnObject.keys(env).find((k)=>k.toLowerCase()===name.toLowerCase())??name}functionexpand(value: string,env: Record<string,string|undefined>){returnvalue.replace(/%([^%]+)%/g,(all,name: string)=>env[keyOf(env,name)]??all)}exportdefault{id: "refresh-env",setup: async(ctx: any)=>{if(process.platform!=="win32")returnawaitctx.shell.hook("create.before",(input: {env: Record<string,string|undefined>})=>{constenv=input.envconstpaths: string[]=[]for(constkeyofKEYS){for(constvofread(key)){constvalue=v.type==="REG_EXPAND_SZ" ? expand(v.value,env) : v.valueif(v.name.toLowerCase()==="path")paths.push(...value.split(";"))elseenv[keyOf(env,v.name)]=value}}if(paths.length===0)return// Registry PATH first (system, then user), then keep any extra entries already present.constpathKey=keyOf(env,"Path")constmerged: string[]=[]for(constpof[...paths, ...(env[pathKey]??"").split(";")]){if(p&&!merged.some((m)=>m.toLowerCase()===p.toLowerCase()))merged.push(p)}env[pathKey]=merged.join(";")})},}
What this does and doesn't cover:
It only changes the environment of commands the agent runs through the shell tool.
It doesn't change OpenCode's own process. Provider API keys or HTTP_PROXY used for OpenCode's own requests still need a restart. Covering those would need a new API in OpenCode itself.
For nvm-style switches made inside a shell, rather than in the registry, the registry has nothing new to read. Those still need the tool's own setup or a restart.
Activity
VishvakR commentedon Sep 14, 2026
this isn't really opencode holding onto old values, a process gets its env when it starts and windows doesn't push PATH changes into processes that are already running. same reason the Git Bash window you had open won't see the new PATH either.
on 2.0.3 the cli snapshots its env at launch (
Env.session()inpackages/cli/src/env.ts) and the tui sends it to the session throughsession.environmentwhen you open it, and the shell tool spawns with that. so you shouldn't lose anything by restarting, open a fresh terminal and runopencode --continue(or pick the session again) and the new PATH goes into that session. history is stored, it's not dropped on restart.an actual in-app refresh would mean reading the user/system env out of the registry on windows and deciding how it merges with what the session already has, which seems like a design call for the team more than a quick PR.
XXLxhPLMM commentedon Sep 14, 2026
To add a practical use case to this discussion:
I frequently need to configure proxy settings (
HTTP_PROXY,HTTPS_PROXY,NO_PROXY, etc.) or other environment variables that should only apply to OpenCode — not to my entire system. For example:PATHentries for project-specific CLI toolsWhat I think would help:
Config-level environment overrides — Allow setting environment variables in
opencode.jsonc(global or project-level) that are applied to all sessions spawned by OpenCode. Something like:{ "environment": { "HTTP_PROXY": "http://127.0.0.1:7890", "PATH": "${PATH};D:\\Tools\\gh\\bin" } }TUI/Desktop env editor — A built-in UI (accessible via a shortcut or command) to view and edit environment variables for the current session or project, without needing to restart OpenCode.
Per-session env refresh — When starting a new session (not restarting OpenCode), re-read the current system environment and merge it with any config-level overrides. This way, even if the running OpenCode process has stale env vars, a fresh session picks up the latest.
This would solve the proxy use case cleanly: I set
HTTP_PROXYin my project'sopencode.jsonc, and every session in that project uses it for all outbound requests — regardless of what the host terminal's environment looks like.XXLxhPLMM commentedon Sep 14, 2026
Quick follow-up question: if I modify the system environment variables and then run
opencode service restart, would the new sessions pick up the updated environment without losing existing session history? Or does the service also snapshot the env at its own launch time?VishvakR commentedon Sep 14, 2026
put up a draft for this anyway, it adds a windows-only
/refresh-envcommand in the tui that reads the Machine and User variables from the registry through powershell and pushes them into the open session.it only adds things: new PATH entries get appended and variables the session doesn't have get added, nothing existing gets replaced. that keeps the PATH entries Git Bash sets up for itself, but it also means an edited value like
HTTP_PROXYwon't change until restart. if overwriting non-PATH vars is preferred i can switch it. haven't been able to run it on windows myself, so it'd be good if someone could try it there.VishvakR commentedon Sep 14, 2026
yeah the service snapshots its env too. it gets spawned as a detached child of whichever opencode process starts it, with that process's env plus anything you set through
opencode service set env(spawnServiceContenderinpackages/client/src/service-contender.ts). soopencode service restartrun from a terminal you opened after changing the vars gives the service the new env, and history is fine since sessions are stored, not held by the service process. the cli restart does close persistent terminals though. the tui's/restartwon't help here, that respawns the service from the tui process which still has the old env.the catch is the shell tool. once the tui has pushed a session env it spawns with
sessionEnvironment ?? process.env(packages/core/src/shell.ts), and an open tui re-pushes its own launch snapshot as soon as it reconnects. so a service restart updates what the service does itself, provider requests and mcp servers, but bash commands in a tui that was already open still get the old PATH. for those you need to reopen the tui from a new terminal,opencode --continue.for the proxy case
opencode service set env HTTP_PROXY http://127.0.0.1:7890already exists and sticks across restarts, same caveat that it applies to the service process and not to shell commands in a tui session.opencodejr commentedon Oct 28, 2026
Thanks for the clear write-up! You're asking for a way to pick up changed environment variables (like a new
PATHentry) in a running OpenCode session, without a restart. Right now OpenCode reads its environment once at startup, so this works as designed today. It's a reasonable improvement, though, and maintainers will consider it.In the meantime, a plugin can cover the most common case: commands run by the shell tool (e.g.
gh --versionafter editing PATH in System Settings). The plugin below re-reads your user and system environment from the Windows registry before every shell command. NewPathentries go first, and any entries OpenCode already had are kept.Save it as
~/.config/opencode/plugins/refresh-env.ts(or.opencode/plugins/refresh-env.tsin a project), then restart OpenCode once:What this does and doesn't cover:
HTTP_PROXYused for OpenCode's own requests still need a restart. Covering those would need a new API in OpenCode itself.