Skip to content

Desktop: Denying a tool permission silently stops the agent loop #30726

Closed as not planned

Description

@claell

Description

In OpenCode Desktop, denying a tool permission prompt silently stops the current agent loop by default.

This is technically consistent with the behavior discussed in #7730, where continue_loop_on_deny was given as the workaround. But in the Desktop GUI this is surprising: the prompt reads like the user is denying one specific tool call, not aborting the whole agent turn.

Expected behavior

Ideally one of these should happen:

  • Denying a tool permission continues the loop by default and sends the rejected tool result back to the model
  • Or Desktop makes the behavior explicit with actions such as "Reject and stop" and "Reject and continue"
  • Or the permission prompt surfaces the experimental.continue_loop_on_deny option / documents it clearly in the UI

Observed behavior

On Windows with OpenCode Desktop 1.15.13:

  • The model requests one or more tools
  • Desktop shows a permission prompt
  • The user denies one requested tool call
  • OpenCode records the denied tool as a tool error: The user rejected permission to use this specific tool call.
  • The current agent loop stops
  • No follow-up model request is sent with the denied tool result

This can look to the user like the model or provider stopped mid-task, even though the client locally ended the loop after the permission denial.

Why this is confusing

Other agent tools commonly treat a denied tool call as information for the model: "that tool call was rejected; try a different approach." In Desktop, the current default feels like a hidden "abort turn" action.

The experimental option works around this:

{
  "experimental": {
    "continue_loop_on_deny": true
  }
}

But users are unlikely to discover that from the Desktop permission prompt itself.

Environment

  • OpenCode Desktop 1.15.13
  • Windows
  • OpenAI-compatible provider

Related issues

Activity

  1. claell commented on Jun 5, 2026

    @claell
    Author

    Following up on this with some broader context after looking into the permission and sandbox landscape a bit more.

    The current overall setup is honestly quite confusing. There are multiple layers that interact in non-obvious ways: permission rules, continue_loop_on_deny as a hidden experimental flag, the Desktop prompt looking like a per-tool denial but actually aborting the whole turn, and a bunch of open issues where deny rules are silently ignored or bypassed (#25515, #28150, #23519, #28682). It's hard to tell what's intentional, what's a bug, and what's just underdocumented.

    One thing I've been thinking about: the stop-on-deny default might actually make some sense as long as the permission system is the only enforcement layer. If the model gets a "denied" signal, it could try to find clever workarounds — writing a script to the working directory and executing that, using a different tool, or escalating in unexpected ways. And without a real sandbox, the model has full bash access, so there's not much stopping it. The permission system alone isn't really a security boundary.

    That argument only holds if there's no proper sandbox though. I recently left some thoughts on #2242 about this — with an external sandbox (bubblewrap, Docker, Landlock, etc.), a denial could safely be fed back to the model, because even if it tries to be clever, the sandbox blocks actual boundary violations at the OS level. The model can retry or try alternatives, but can't escape.

    So maybe the path forward is something like:

    1. Get proper sandbox support in place (Is there a way to sandbox the agent ? #2242)
    2. Then change the default to continue the loop on deny, with explicit "Abort" / "Continue" buttons in the Desktop UI
    3. Until then, at least surface continue_loop_on_deny in the Desktop prompt so users can make an informed choice

    Right now the whole thing feels like it's in an awkward middle ground — neither safe enough to let the model keep going, nor transparent enough about what "deny" actually does.

  2. github-actions commented on Aug 5, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions