Skip to content

[BUG]: TUI: explicit stop is not sticky — each stop message re-prompts for the same permission until the session is closed #53125

Open

Description

@snesen

Description

Interrupting a turn and then sending an explicit stop message does not stop the agent. The next assistant step re-requests permission for the same action, so every stop message produces exactly one new permission prompt. There is no session-level "user asked to stop" state that survives into the following step, and the only way to end the loop is to close the session.

Measured from one session (ses_f0f92404…, all times UTC):

time event
10:29:27 idle → outcome=interrupted
10:29:31 step → tool call #1 shell, denied after 4.4s
10:29:48 user: "stop"
10:35:53 step → tool call #2 shell — pending 8.7 min before denied
10:44:41 user: "stop"
10:44:54 step → tool call #3 shell, denied after 1.4 min
10:46:21 idle → outcome=interrupted; user closes session

Two things make this worse than a normal rejected call:

  1. The pending request is not cancellable and is not tied to the turn. During the 8.7-minute window the only action available was Reject, which per [BUG]: Desktop: denying a tool permission prompt silently stops the whole agent turn (replacement for stale-closed #30726) #44255 ends the turn. The user is funnelled into the exact behaviour already reported there.
  2. The signal the model receives is ambiguous. Each attempt ends with {"type":"aborted","message":"The user declined this tool call"} plus finish=error. Nothing distinguishes "reject this one call, continue" from "I want you to stop". The model reasonably reads it as a failed approach and retries, so the loop persists across turns.

All three calls record executed: false, so nothing ran — impact is a prompt loop, not data loss.

Also worth noting: no message=asking … permission= line is written to opencode.log on 2.0.19 (last one is dated 2026-09-03 on 1.18.x), so this had to be reconstructed from the session_message table.

Steps to reproduce

  1. Configure a tool to ask (no permission block was set here; shell prompted via external-directory access to paths outside the project).
  2. Run a session and give a task that requires that tool.
  3. Interrupt the turn, then send a plain-language stop message ("stop", "bro dursana").
  4. Reject the permission prompt that appears.
  5. Repeat step 3–4: each new stop message yields another prompt for the same action.
  6. Only closing the session ends it.

Intermittent in the sense that it needs a multi-step task; deterministic once the loop starts (3/3 prompts here).

OpenCode version

2.0.19 (channel=latest; 2.0.22 available). Long-lived opencode serve --service process, client attached/detached across the session.

Plugins

None. Two local stdio MCP servers configured (blender, unity), unrelated to the failure.

Operating System

WSL2: Linux 6.18.33.2-microsoft-standard-WSL2 (x64), Windows 11 host, project workspace on /mnt/c.

Terminal

Windows Terminal (WT_SESSION set), TERM=xterm-256color, shell /bin/bash.

Related

#44255 / #45273 (reject semantics), #44747 (stop/interrupt no-ops), #37007 / #40829 (abort waiting on tool), #51224 / #52846 (pending-request lifecycle). The distinction here is that no step carries forward an aborted/halted state, so the retry happens in a new turn rather than within one.

Activity

  1. github-actions commented on Oct 4, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of an existing issue. Please check:

    • #36644: reports the agent continuing after rejecting an action and pressing Escape; this issue adds explicit stop messages and repeated prompts for the same permission across turns.
  2. opencodejr commented on Oct 27, 2026

    @opencodejr

    Thanks for the detailed timeline. It makes the loop easy to follow.

    As far as I can tell, each piece is working as designed in v2: declining a permission ends the current turn and marks the call as aborted ("The user declined this tool call"). Sending "stop" then starts a normal new turn, and the model decides to try the same shell call again, which correctly asks for permission again. So what you're describing is a request for new behaviour:

    • a session-level "user asked to stop" state that carries into later turns
    • a rejection that tells the model "stop the task" rather than "this call failed"
    • pending permission prompts that can be cancelled by interrupting, or that are tied to the turn, instead of Reject being the only way out

    I've marked this as a feature request so maintainers can consider it. I can't say whether or when it will be picked up.

    Related issues:

    In the meantime, a stop message that is more explicit about tools, e.g. "stop, do not call any more tools", may help, or you can allow or deny that specific external-directory path in your permission config so the prompt doesn't come back.

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