free models: subagent fails with "free tier can only be used from within OpenCode" when deny-first permissions leave the agent with no allowed actions · Issue #54882 · anomalyco/opencode · GitHub
Skip to content

free models: subagent fails with "free tier can only be used from within OpenCode" when deny-first permissions leave the agent with no allowed actions #54882

Closed as duplicate

Description

@gelnuro

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 plugins key in the project or global config

Reproduction

  1. Project config .opencode/opencode.jsonc contains a deny-first policy:

    "permissions": [
      { "action": "*", "resource": "*", "effect": "deny" }
    ]
  2. 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.

  3. 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.

  4. Actual result:

    {"error":{"type":"tool.execution","message":"Subagent failed (sessionID: ses_...): OpenCode's free tier can only be used from within OpenCode"}}
    
  5. Control - .opencode/agents/analytics-performance.md, same model: 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 allow rule. 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

  1. opencode-agent commented on Oct 12, 2026

    @opencode-agent
    Contributor

    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 a deny rule 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: its shell allow for git log * brings the shell tool back.

    Possible duplicates and closely related issues, ordered by likelihood:

    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 ask instead of deny, or add a narrow shell allow as you did. If you have results that differ from that (for example, a read-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.

  2. gelnuro commented on Oct 12, 2026

    @gelnuro
    Author

    Follow-up with a controlled test of which allow rule is actually required.

    Both configs use the same deny-first project policy:

    "permissions": [
      { "action": "*", "resource": "*", "effect": "deny" }
    ]

    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:

    permissions:
      - action: read
        resource: ".opencode/opencode.jsonc"
        effect: allow
      - action: shell
        resource: "git log *"
        effect: allow

    Result: PROBE-OK, repeated several times across the session.

    Config B - one shell rule only, the read rule commented out:

    permissions:
    #   - action: read
    #     resource: ".opencode/opencode.jsonc"
    #     effect: allow
      - action: shell
        resource: "echo 'Hello!'"
        effect: allow

    Result: 4 consecutive attempts all failed:

    {"error":{"type":"tool.execution","message":"Subagent failed (sessionID: ses_...): OpenCode's free tier can only be used from within OpenCode"}}
    

    So under a deny-first policy a single shell allow is not sufficient. The agent also needs a read allow covering the project's opencode.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.

  3. opencode-agent commented on Oct 12, 2026

    @opencode-agent
    Contributor

    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 narrow allow puts 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 with bash and read allowed, 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 keeps read, which happens to be enough for this check. The .opencode/opencode.jsonc path 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.

  4. gelnuro commented on Oct 12, 2026

    @gelnuro
    Author

    Confirmed the prediction: swapping the read resource from .opencode/opencode.jsonc to an unrelated README.md still returns PROBE-OK, with the same shell: "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):

    Agent permissions: Result
    none fails
    shell only 4/4 failures
    read + shell (config file) PROBE-OK repeatedly, some later failures
    read (README.md) + shell PROBE-OK

    Nothing 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.

  5. opencode-agent commented on Oct 12, 2026

    @opencode-agent
    Contributor

    Thanks for checking. Good to know the README.md read 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.

  6. opencode-agent commented on Oct 13, 2026

    @opencode-agent
    Contributor

    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 read allow (any file) plus a narrow shell allow to the agent gets past the error, as your tests showed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions