Repository navigation
Description
Summary
With a deny-first permissions policy in project config, a subagent running on a free OpenCode model that has no permissions: exceptions cannot be spawned: the call fails with OpenCode's free tier can only be used from within OpenCode. Adding a single narrow allow rule to the same agent makes the identical call succeed. The error points at the free-tier gate, but the only thing that changed is the agent's permission set.
Environment
- opencode version: v2.0.26
- OS: Linux 6.1.99-rockchip-rk3588 aarch64 (arm64)
- Terminal: TERM=xterm-256color, TERM_PROGRAM=vscode
- Shell: /usr/bin/zsh
- Install/channel: release binary reporting v2.0.26
- Active plugins: none registered - no
pluginskey in the project or global config
Reproduction
-
Project config
.opencode/opencode.jsonccontains a deny-first policy:"permissions": [ { "action": "*", "resource": "*", "effect": "deny" } ]
-
Define a subagent
.opencode/agents/technical-writer.md:--- description: Writes concise, accurate developer documentation and user-facing explanations. mode: subagent model: opencode/mimo-v2.6-flash-free ---
No
permissions:block, so the global deny applies to every action. -
Launch it from a session that is already inside OpenCode, with a trivial prompt:
Reply with exactly PROBE-OK and nothing else. Do not call tools or modify files.
-
Actual result:
{"error":{"type":"tool.execution","message":"Subagent failed (sessionID: ses_...): OpenCode's free tier can only be used from within OpenCode"}} -
Control -
.opencode/agents/analytics-performance.md, samemodel:and same prompt, with a permissions block:--- permissions: - action: read resource: ".opencode/opencode.jsonc" effect: allow - action: shell resource: "git log *" effect: allow ---
Result:
PROBE-OK
Expected Behavior
A free model launched as a subagent from a session that is already inside OpenCode should authenticate the same way the primary session does. The agent's permissions: set should gate tool calls; it should not change whether the free-tier gate considers the call to be "from within OpenCode". At minimum, a permission problem should be reported as a permission error rather than as a free-tier eligibility error.
Actual Behavior
Every free-model subagent with no allow rules fails with OpenCode's free tier can only be used from within OpenCode. The same agent definition succeeds as soon as at least one narrow allow rule exists - observed with a single shell allow (git log *) and previously with read on .opencode/opencode.jsonc. Four free-model agents in this project are affected: technical-writer, qa-engineer, documentation-auditor, product-manager.
Additional Context
- Suspected cause: the free-tier gate inspects the tool/permission surface of the session. An agent whose actions are all denied ends up with an empty or near-empty tool set, which the gate appears to misread as "not inside OpenCode". Possibly related to tool-set gating in console: free-tier 403 rejects restricted subagents even with bash allowed #54744.
- Observed additionally: identical probes against the permitted control agent occasionally returned the same free-tier error under unchanged config until an
opencode service restart, so the check may also be intermittent. - Workaround in use: give each free-model agent at least one narrow
allowrule. This forces a permission rule that exists only to satisfy the gateway, which is exactly what a deny-first policy is meant to avoid.
Activity
opencode-agent commentedon Oct 12, 2026
Thanks for the detailed report and the control experiment! I think this is a duplicate of #50627. The free-tier check rejects requests whose tool list has no shell (
bash) tool, and adenyrule removes tools from that list. Your{ "action": "*", "resource": "*", "effect": "deny" }with no agent exceptions removes every tool, shell included. That fits your control agent working: itsshellallow forgit log *brings the shell tool back.Possible duplicates and closely related issues, ordered by likelihood:
denyrule on a custom agent breaks free-tier models with this same error. This is where the tool-list cause was worked out."*"deny strips every tool from the agent.explore,plan) hit the same error when shell is denied.Until this is fixed, people in those threads get past it by keeping the shell tool in the request: set the base shell rule to
askinstead ofdeny, or add a narrow shellallowas you did. If you have results that differ from that (for example, aread-only allow working consistently), it would help to add them to #50627.The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
gelnuro commentedon Oct 12, 2026
Follow-up with a controlled test of which allow rule is actually required.
Both configs use the same deny-first project policy:
Same agent (
mode: subagent,model: opencode/mimo-v2.6-flash-free), same prompt ("Reply with exactly PROBE-OK and nothing else. Do not call tools or modify files."), no other config change between the two.Config A - read on the project config + one shell rule:
Result:
PROBE-OK, repeated several times across the session.Config B - one shell rule only, the read rule commented out:
Result: 4 consecutive attempts all failed:
So under a deny-first policy a single
shellallow is not sufficient. The agent also needs areadallow covering the project'sopencode.json(c). That points at the gate needing the session to be able to read the project config file - plausibly the "am I inside OpenCode?" check resolves the project configuration through the agent's own permission surface, so a deny-first policy makes the check fail.Caveat on reliability: even with Config A, some later runs of the same probe returned the free-tier error with no config change, so the check also appears intermittent independently of the rule set.
opencode-agent commentedon Oct 12, 2026
Thanks for running the A/B test, that's a useful data point. I still think this is the same bug as #50627, and your result fits what was found there.
The free-tier check happens on the server, not in OpenCode itself, and it looks at which tools are listed in the model request. It doesn't check whether OpenCode can read your config file. When a tool is denied outright (every rule for it is
deny), OpenCode leaves it out of the request completely. A narrowallowputs the tool back in the list, even if the agent never uses it.The check seems to want more than just
bash. A data point posted on #50627 (from #54744) shows an agent withbashandreadallowed, but other tools left out, still being rejected. So under{ "action": "*", "resource": "*", "effect": "deny" }, your Config B leaves the request with only the shell tool, which isn't enough. Config A also keepsread, which happens to be enough for this check. The.opencode/opencode.jsoncpath itself shouldn't matter. If you want to confirm, replace that resource with an unrelated file (e.g.README.md) and the probe should still pass. Others there also report the check being inconsistent, which fits the occasional failures you saw with Config A.The most useful next step would be to add your Config A/B results (and that check, if you try it) to #50627, where the fix is being tracked. Related issues: #51193 (a
"*"deny removes every tool) and #54744 (restricted allowlists still rejected).Unless you see something that doesn't fit this explanation, the bot will still close this issue as a duplicate of #50627 at the scheduled time.
gelnuro commentedon Oct 12, 2026
Confirmed the prediction: swapping the read resource from
.opencode/opencode.jsoncto an unrelatedREADME.mdstill returnsPROBE-OK, with the sameshell: "echo 'Hello!'"allow alongside it. So the config file path is irrelevant and does not need to be readable — my earlier comment's conclusion was wrong on that point, and no secrets need to be exposed to the agent for the workaround to work.Full matrix (deny-first project policy, subagent on
opencode/mimo-v2.6-flash-free, v2.0.26, same trivial probe throughout):permissions:shellonlyread+shell(config file)PROBE-OKrepeatedly, some later failuresread(README.md) +shellPROBE-OKNothing here contradicts the explanation, so agreed this belongs with #50627. I've posted the matrix there, along with two caveats that may matter for the fix: the two-rule allowlist that passes here sits oddly next to the 8-tool allowlist that reportedly still 403s in #54744, and the intermittency observed with an unchanged allowlist looks like a separate behaviour from the "denied tools are dropped from the request" one.
Happy for this to be closed as a duplicate.
opencode-agent commentedon Oct 12, 2026
Thanks for checking. Good to know the
README.mdread rule works just as well, so the workaround doesn't need the agent to read your config or anything sensitive. And thanks for posting the full matrix and the two caveats on #50627. The odd contrast with the 8-tool allowlist in #54744, and the failures with no config change, are useful for whoever picks up the fix there.The bot will close this issue as a duplicate of #50627 at the scheduled time. Please follow that issue for updates.
opencode-agent commentedon Oct 13, 2026
Closing this as a duplicate of #50627, as agreed above. Your tests matched the cause found there: the free-tier check rejects requests that leave out some of the default tools, and a deny-first policy takes them out. Thanks for posting your results on #50627. Please follow that issue for updates. For now, adding a narrow
readallow (any file) plus a narrowshellallow to the agent gets past the error, as your tests showed.