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
[FEATURE]: Unify shell initialization behavior between user shell and agent bash tool #17792
I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Summary
There is an inconsistency between the user-invoked shell (!) and the agent bash tool.
At the moment:
the user ! shell loads shell init files such as ~/.bashrc
the agent bash tool does not
As a result, the same command can work in the user shell but fail in the agent shell because functions, aliases, exports, or PATH changes from shell init are only available in one path.
Reproduction
Example ~/.bashrc:
myfunc() {
echo ok
}
export -f myfunc
Then compare:
Run myfunc through the user shell (!)
Run the equivalent command through the agent bash tool
Actual behavior
User ! shell can access definitions and environment initialized by shell startup files
Agent bash tool cannot
Expected behavior
These two shell execution paths should behave consistently.
Possible acceptable outcomes:
both load shell init files in the same way, or
both avoid loading shell init files, or
a config/flag makes the behavior explicit and shared between both paths
Notes
The current implementation appears to use different logic for these paths:
packages/opencode/src/session/prompt.ts
user shell path explicitly sources shell init files for some shells
packages/opencode/src/tool/bash.ts
agent bash tool uses spawn(..., { shell }) without equivalent shell init loading
This creates surprising differences between manual shell usage and agent-executed shell commands.
Request
Please unify the shell initialization logic between:
user ! shell
agent bash tool
If exact unification is not desired, please provide a documented configuration option that controls shell init behavior consistently for both paths.
Reacted by SingKS8, agent, VKatWork, joergdw, ceeeeeeeeeeeeeeeeb and Muhammad Arslan
This issue might be a duplicate of existing issues. Please check:
Shell sessions losing $PATH value from parent shell #4968: Shell sessions losing $PATH from parent shell — discusses the same root cause (bash tool spawning non-interactive shells that don't source RC files like ~/.bashrc/~/.zshrc), with proposed solutions including launching interactive shells
+1 on this feature request — hitting the exact same pain, but with a compounding bug that makes it worse.
Our specific symptoms
Agent: OpenCode (kimi-k2.6) on Linux (Omarchy/Arch)
User shell (!): works fine, sources ~/.bashrc, finds all tools
Agent bash tool: fails to find any tools installed in PATH via ~/.bashrc
The compounding bug: literal tilde in inherited PATH
Not only does the agent bash tool not source ~/.bashrc, but the parent OpenCode/Electron process appears to inject a PATH containing a literal unexpanded ~/.local/bin:
$ python3 -c 'import os; print([s for s in os.environ["PATH"].split(":") if "~" in s])'
['~/.local/bin']
Bash does not expand ~ in inherited environment variables — only at the moment of export. So that segment is effectively a broken path.
Evidence: DIL tool directory completely absent from $PATH
$ which task_tool
# "no task_tool in (...)"
$ source~/.bashrc && which task_tool
# /home/moo/Documents/dil_agentic_memory_0001/_shared/scripts/bin/task_tool
They appear to spawn bash as a login shell (bash -l -c) or explicitly source ~/.bashrc, so PATH additions and function definitions are available to the agent.
Request
Please consider:
Spawning agent bash as a login shell (bash -l -c '...') on Linux/macOS, OR
Explicitly expanding tildes in inherited PATH before spawning, OR
Sourcing shell init files before agent command execution.
This would fix the disjoint between ! shell (works) and agent bash tool (broken) that #17792 identifies.
I found a temporary workaround for the current behavior by using an opencode hook to inject my PowerShell profile before every agent bash tool execution.
This makes the agent bash tool load the same profile initialization that I expect in my normal shell session, so aliases/functions/PATH changes from my PowerShell profile become available to agent-executed commands as well.
The $env:__BASH_AUTO_INJECT = 1 marker is necessary as a sentinel. It prevents the hook from injecting the same source command repeatedly if a command is already wrapped. It also helps when the injected command leaks into the visible tool history and the agent later copies or imitates the previous command: the hook can detect the marker and avoid a second injection. Without this guard, commands can become nested like:
This workaround is functional, but it has two drawbacks:
The injected prefix is currently visible in the command shown to the user and/or retained in the agent-visible history.
That increases token usage and can encourage the agent to learn or reproduce implementation details that should ideally remain a transport/runtime concern.
This is very close to the motivation behind #5321, where displayInput would allow a plugin to execute a wrapped command while displaying the original, unwrapped command. I agree with that direction. The hook/plugin layer would be much safer and cleaner if opencode officially supported a way for tool.execute.before hooks to distinguish between:
the command actually executed by the runtime, and
the command shown in the UI / persisted into agent-visible history.
Related work also appears in #6927, which mentions #5321 as related to tool input/output display behavior.
So while this hook is a usable temporary workaround, I would still prefer an official solution that either:
unifies shell initialization between user ! shell and agent bash tool directly, or
provides a documented hook/display API so wrappers can safely hide injected runtime prefixes.
This would improve security, reduce token usage, and avoid training the agent to copy internal wrapper commands.
As a Simplified Chinese user on Windows, I'd like to add our pain point.
On Windows, the system code page defaults to 936 (GBK), but most modern development tools expect UTF-8 (65001). The typical fix is adding chcp 65001 to the PowerShell profile. However, since the agent bash tool doesn't load the PowerShell profile, Chinese characters in command output become garbled. This significantly hurts the experience for Chinese-speaking developers.
Note that enabling the "Beta: Use Unicode UTF-8 for worldwide language support" option in Windows region settings is not a viable workaround for Chinese users — it breaks text rendering in many legacy applications, causing garbled characters in non-Unicode programs. This is a well-known compatibility issue reported by many Chinese users.
A unified shell init behavior (or at least making the ! shell and agent bash tool consistent) would resolve this and make OpenCode much more accessible to the Chinese developer community.
For anyone waiting on this, here's a working workaround on Linux using BASH_ENV.
Create ~/.config/opencode/shell-init.sh with your aliases and env:
#!/bin/bash# Source whatever files define your aliases and env.# Only load non-interactive-safe stuff here.# Skip interactive tools like starship, zoxide, mise -- they break in dumb terminals.
[ -f"$HOME/.bash_aliases" ] &&source"$HOME/.bash_aliases"
[ -f"$HOME/.bash_env" ] &&source"$HOME/.bash_env"
Customizing shell-init.sh: Source wherever your aliases live. Locations for me:
~/.bash_aliases -- standalone alias file
~/.bash_env -- environment variables
~/.profile or ~/.bash_profile -- PATH, login exports
Your distro's default alias file (e.g. /etc/skel/.bash_aliases)
Avoid sourcing full ~/.bashrc, it usually has interactive-only stuff (prompts, completions) that errors in non-TTY context.
Why 2 files: combining them causes an infinite loop since bash sources BASH_ENV on start.
BASH_ENV is auto-sourced by bash in non-interactive mode in OpenCode, bypassing the ~/.bashrc interactive guard (available by default) without removing it.
Thanks for the report — starting with OpenCode 2.0.0, user shell commands and the agent's shell tool share non-interactive startup behavior rather than explicitly sourcing different shell profiles. No opt-in is needed: ! commands and agent shell commands both use this behavior, so interactive aliases/functions should not be assumed available. Update with opencode upgrade or npm i -g @opencode/cli@latest (desktop: update the app). Please comment or reopen if the two paths still initialize differently on that version.
Activity
github-actions commentedon Mar 16, 2026
This issue might be a duplicate of existing issues. Please check:
~/.bashrc/~/.zshrc), with proposed solutions including launching interactive shells!prefix), causing inconsistent behaviorIf your issue is substantially the same as one of these, please consider adding detail there instead.
zigmoo commentedon Apr 29, 2026
+1 on this feature request — hitting the exact same pain, but with a compounding bug that makes it worse.
Our specific symptoms
!): works fine, sources~/.bashrc, finds all toolsbashtool: fails to find any tools installed inPATHvia~/.bashrcThe compounding bug: literal tilde in inherited PATH
Not only does the agent
bashtool not source~/.bashrc, but the parent OpenCode/Electron process appears to inject a PATH containing a literal unexpanded~/.local/bin:Bash does not expand
~in inherited environment variables — only at the moment ofexport. So that segment is effectively a broken path.Evidence: DIL tool directory completely absent from $PATH
(DIL Distributed Intent Ledger)
Our
~/.bashrcadds:After agent spawns
bash -c:Relationship to other issues
Shell sessions losing $PATH value) — related, but about PATH being minimal, not about missing~/.bashrcsourcing entirely.Web UI Terminal no longer sources .bashrc) — was fixed for the user!shell, but the agentbashtool still doesn't source it.preserve nix/direnv PATH in login shell for ! commands) — fixed PATH preservation for!commands, not agent bash.Tilde (~) bug) — another user hit tilde issues and noted "I'm not having this issue in claude or codex."Why Claude/Codex work
They appear to spawn bash as a login shell (
bash -l -c) or explicitly source~/.bashrc, so PATH additions and function definitions are available to the agent.Request
Please consider:
bashas a login shell (bash -l -c '...') on Linux/macOS, ORThis would fix the disjoint between
!shell (works) and agentbashtool (broken) that #17792 identifies.PS: Thanks to https://github.com/bakabaka9405 for the existing Issue to Work With!
bakabaka9405 commentedon Apr 30, 2026
I found a temporary workaround for the current behavior by using an opencode hook to inject my PowerShell profile before every agent
bashtool execution.This makes the agent
bashtool load the same profile initialization that I expect in my normal shell session, so aliases/functions/PATH changes from my PowerShell profile become available to agent-executed commands as well.The
$env:__BASH_AUTO_INJECT = 1marker is necessary as a sentinel. It prevents the hook from injecting the same source command repeatedly if a command is already wrapped. It also helps when the injected command leaks into the visible tool history and the agent later copies or imitates the previous command: the hook can detect the marker and avoid a second injection. Without this guard, commands can become nested like:This workaround is functional, but it has two drawbacks:
This is very close to the motivation behind #5321, where
displayInputwould allow a plugin to execute a wrapped command while displaying the original, unwrapped command. I agree with that direction. The hook/plugin layer would be much safer and cleaner if opencode officially supported a way fortool.execute.beforehooks to distinguish between:Related work also appears in #6927, which mentions #5321 as related to tool input/output display behavior.
So while this hook is a usable temporary workaround, I would still prefer an official solution that either:
!shell and agentbashtool directly, orThis would improve security, reduce token usage, and avoid training the agent to copy internal wrapper commands.
CresentMoon commentedon Jun 14, 2026
Xarianne commentedon Jul 20, 2026
I have ran into this issue as well (just making the interest in this fix known from another user.)
ch-arslanahmad commentedon Sep 4, 2026
For anyone waiting on this, here's a working workaround on Linux using
BASH_ENV.~/.config/opencode/shell-init.shwith your aliases and env:~/.config/opencode/shell-wrapper.sh(replace path):opencode.json:{ "shell": "/home/youruser/.config/opencode/shell-wrapper.sh" }4.
chmod +xboth files, restart OpenCode.Customizing
shell-init.sh: Source wherever your aliases live. Locations for me:~/.bash_aliases-- standalone alias file~/.bash_env-- environment variables~/.profileor~/.bash_profile-- PATH, login exports/etc/skel/.bash_aliases)Avoid sourcing full
~/.bashrc, it usually has interactive-only stuff (prompts, completions) that errors in non-TTY context.Why 2 files: combining them causes an infinite loop since bash sources
BASH_ENVon start.BASH_ENVis auto-sourced by bash in non-interactive mode in OpenCode, bypassing the~/.bashrcinteractive guard (available by default) without removing it.neriousy commentedon Oct 20, 2026
Thanks for the report — starting with OpenCode 2.0.0, user shell commands and the agent's shell tool share non-interactive startup behavior rather than explicitly sourcing different shell profiles. No opt-in is needed:
!commands and agent shell commands both use this behavior, so interactive aliases/functions should not be assumed available. Update withopencode upgradeornpm i -g @opencode/cli@latest(desktop: update the app). Please comment or reopen if the two paths still initialize differently on that version.