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
tools: built-in shell tool advertised to the model as "shell_client", but runtime only executes "shell" #56193
On OpenCode v2.0.31 (Windows), sessions with certain models (served through a custom
OpenAI-compatible provider) receive an agent-facing tool catalog / system instructions that:
list a tool named shell_client (description: "Commands run on Windows using powershell"), and
mark the built-in shell tool as "a placeholder that does nothing — do not call it".
At runtime the opposite is true. Verified empirically in the same session:
calling shell_client is always rejected: {"error":{"type":"tool.execution","message":"No tool named \"shell_client\" is currently available. Please use a tool from the available tool list."}}
calling shell executes normally on the same host (PowerShell), including workdir/timeout params.
Impact: any session where the model follows the presented catalog cannot run terminal commands
at all — lint, test, build, and git are fully blocked for the whole project.
Ruled out as the source:
user config / plugins: none configured at reproduction time
MCP server: connected and working (37 tools, none named shell_client)
provider/relay side: the relay only proxies the completion stream; the tool list and tool
execution are generated host-side by OpenCode
opencode.log shows no registration event for the name shell_client
Plugins
No response
OpenCode version
2.0.31
Steps to reproduce
Observe the tool list presented to the model: shell_client is listed as a runnable tool, while shell is marked "a placeholder that does nothing — do not call it".
Ask the model to run any terminal command e.g. "run git status".
The model calls shell_client → hard-failed with
"No tool named "shell_client" is currently available. Please use a tool from the available tool list."
Calling shell with the identical arguments succeeds on the same host.
Reproducible consistently every session with the affected models.
I checked the OpenCode source for v2.0.31 and the current dev branch. Neither the name shell_client nor the text "a placeholder that does nothing — do not call it" appears anywhere in it. OpenCode registers only one shell tool, shell, and gives it the description "Commands run on Windows using powershell". So it looks like something between OpenCode and the model copied the real shell tool under the name shell_client and told the model that shell is a placeholder. The No tool named "shell_client" error is then expected, because OpenCode never registered that tool. Some relays and proxies rename client tools that clash with their own built-in tools this way.
To confirm where the rename happens, could you share:
Your provider config from opencode.json: the npm package, baseURL, and which relay software or service it points to. Please remove API keys.
Which models are affected and which are not, with their exact model IDs.
The tool list OpenCode actually sends, if you can capture it. For example, log the raw request body at the relay, or check whether the relay has a request log. Does the outgoing request contain shell or shell_client?
Whether it still happens when you use the same model through its original provider directly, without the relay, if that's possible.
You can reply here with the details or edit the issue. If you edit it, please also leave a comment saying you've updated it, so we know when you're done.
Root cause found — this is not an OpenCode bug. Closing as not planned.
The renaming layer between OpenCode and the model is 9Router, tracked upstream: decolua/9router#4971 ("fingerprint pass renames the caller's shell to shell_client
and leaks a placeholder note, because the captured definition is Linux-only"),
fix in decolua/9router#4972.
What happens on the 9Router path:
Its fingerprint pass treats a caller tool as "conflicting" whenever the tool's
description text differs from a frozen, Linux-captured definition (=== / JSON.stringify comparison of a ~533-char description).
It then renames shell → shell_client (alias restored on the response side),
appends a placeholder shell tool, and injects
"Do not call the shell tool; it is a placeholder that does nothing..." into
the system prompt.
OpenCode of course only registers shell, so every shell_client call bounces
with the No tool named "shell_client" error from this report.
Windows angle (per fix: improve code quality, type safety, and documentation #4971): the frozen description says "Commands run on Linux
using bash." while OpenCode on Windows composes "Commands run on Windows using
pwsh." — a 2-character difference inside the description is enough to trigger
the rename for every Windows client.
Answers to the triage questions:
Provider config: @ai-sdk/openai-compatible, baseURL
(a personal OpenAI-compatible relay), with 9Router in the serving chain.
Affected: glm-5.3-flash; the rename happens per-request regardless of model,
on Windows clients.
Outgoing request from OpenCode contains shell; the rename happens after
capture inside 9Router, so it never appears in OpenCode's own logs.
a small plugin registering shell_client as a real tool (bridge), or
a global AGENTS.md instructing the model to call shell — with that, the model
self-corrects after the first failed attempt.
Thanks for the fast triage — the bot's guess ("some relays and proxies rename
client tools that clash with their own built-in tools this way") turned out to be
exactly right.
Thanks for tracking this down, @JustSEMI, and for writing up the details.
That matches what's in OpenCode: shell is the only shell tool it registers, and the description changes with the platform ("Commands run on Windows using …"). That's why a check comparing against a saved Linux description renames the tool for every Windows client. The No tool named "shell_client" error is OpenCode correctly rejecting a name it never registered.
The fix belongs in 9Router (decolua/9router#4971, fix in decolua/9router#4972). Until it ships, your workarounds should do: a small plugin that registers shell_client and forwards it to shell, or an AGENTS.md note telling the model to call shell. Closing this as not planned on the OpenCode side makes sense.
Closing this as not planned. As @JustSEMI found, the shell → shell_client rename and the "placeholder" note come from 9Router, not from OpenCode. 9Router renames OpenCode's shell tool for Windows clients because its description doesn't match 9Router's saved Linux copy. The fix belongs upstream in decolua/9router#4971 (fix in decolua/9router#4972).
Until it ships, you can register a small plugin that adds shell_client and forwards calls to shell, or add an AGENTS.md note telling the model to call shell. If it still happens without 9Router in the chain, please open a new issue with the details. Thanks again for the thorough investigation!
Activity
opencode-agent commentedon Oct 16, 2026
Thanks for the detailed report, @JustSEMI.
I checked the OpenCode source for v2.0.31 and the current
devbranch. Neither the nameshell_clientnor the text "a placeholder that does nothing — do not call it" appears anywhere in it. OpenCode registers only one shell tool,shell, and gives it the description "Commands run on Windows using powershell". So it looks like something between OpenCode and the model copied the realshelltool under the nameshell_clientand told the model thatshellis a placeholder. TheNo tool named "shell_client"error is then expected, because OpenCode never registered that tool. Some relays and proxies rename client tools that clash with their own built-in tools this way.To confirm where the rename happens, could you share:
opencode.json: thenpmpackage,baseURL, and which relay software or service it points to. Please remove API keys.shellorshell_client?You can reply here with the details or edit the issue. If you edit it, please also leave a comment saying you've updated it, so we know when you're done.
Related, though probably a different problem:
No tool named …(plugin and Code Mode tools)JustSEMI commentedon Oct 16, 2026
Root cause found — this is not an OpenCode bug. Closing as not planned.
The renaming layer between OpenCode and the model is 9Router, tracked upstream:
decolua/9router#4971 ("fingerprint pass renames the caller's shell to shell_client
and leaks a placeholder note, because the captured definition is Linux-only"),
fix in decolua/9router#4972.
What happens on the 9Router path:
description text differs from a frozen, Linux-captured definition (
===/JSON.stringifycomparison of a ~533-char description).shell→shell_client(alias restored on the response side),appends a placeholder
shelltool, and injects"Do not call the
shelltool; it is a placeholder that does nothing..." intothe system prompt.
shell, so everyshell_clientcall bounceswith the
No tool named "shell_client"error from this report.using bash." while OpenCode on Windows composes "Commands run on Windows using
pwsh." — a 2-character difference inside the description is enough to trigger
the rename for every Windows client.
Answers to the triage questions:
@ai-sdk/openai-compatible, baseURL(a personal OpenAI-compatible relay), with 9Router in the serving chain.
glm-5.3-flash; the rename happens per-request regardless of model,on Windows clients.
shell; the rename happens aftercapture inside 9Router, so it never appears in OpenCode's own logs.
POSTing to /v1/chat/completions directly, no client involved).
Local workarounds while the 9Router fix ships:
shell_clientas a real tool (bridge), orshell— with that, the modelself-corrects after the first failed attempt.
Thanks for the fast triage — the bot's guess ("some relays and proxies rename
client tools that clash with their own built-in tools this way") turned out to be
exactly right.
opencode-agent commentedon Oct 16, 2026
Thanks for tracking this down, @JustSEMI, and for writing up the details.
That matches what's in OpenCode:
shellis the only shell tool it registers, and the description changes with the platform ("Commands run on Windows using …"). That's why a check comparing against a saved Linux description renames the tool for every Windows client. TheNo tool named "shell_client"error is OpenCode correctly rejecting a name it never registered.The fix belongs in 9Router (decolua/9router#4971, fix in decolua/9router#4972). Until it ships, your workarounds should do: a small plugin that registers
shell_clientand forwards it toshell, or anAGENTS.mdnote telling the model to callshell. Closing this as not planned on the OpenCode side makes sense.opencode-agent commentedon Oct 19, 2026
Closing this as not planned. As @JustSEMI found, the
shell→shell_clientrename and the "placeholder" note come from 9Router, not from OpenCode. 9Router renames OpenCode'sshelltool for Windows clients because its description doesn't match 9Router's saved Linux copy. The fix belongs upstream in decolua/9router#4971 (fix in decolua/9router#4972).Until it ships, you can register a small plugin that adds
shell_clientand forwards calls toshell, or add anAGENTS.mdnote telling the model to callshell. If it still happens without 9Router in the chain, please open a new issue with the details. Thanks again for the thorough investigation!