Skip to content

ACP: premature tool_call_update with in_progress clobbers pending session/request_permission dialog #14301

@olehpalianytsiagr

Description

@olehpalianytsiagr

Description

When OpenCode sends a session/request_permission request to an ACP client, it simultaneously (in the same message batch) sends a tool_call_update notification transitioning the same tool call to status: "in_progress". This happens before the client has responded to the permission request.

Per the ACP spec:

  • pending: "The tool call hasn't started running yet because the input is either streaming or awaiting approval"
  • in_progress: "The tool call is currently running"

The premature in_progress update causes ACP clients (e.g. agent-shell) to overwrite the permission dialog UI with a regular status display, making it impossible for the user to approve or reject the permission. The tool call then hangs indefinitely.

This affects all permission types — both external_directory and bash permissions exhibit the same behavior.

ACP log showing the race (same toolCallId):

① tool_call           → status: "pending",     title: "write",               kind: "edit"
② request_permission  → status: "pending",     title: "external_directory",  kind: "other"   (id: 2, awaiting response)
③ tool_call_update    → status: "in_progress", title: "write",               kind: "edit"    (arrives before client responds to ②)

Raw JSON showing ② and ③ arriving in the same TCP read (same batch):

{"jsonrpc":"2.0","id":2,"method":"session/request_permission","params":{"sessionId":"...","toolCall":{"toolCallId":"toolu_01Pi2R6Ko5TVVAX9SsWw1qe2","status":"pending","title":"external_directory","rawInput":{"filepath":"/tmp/dummy-test-primary.txt","parentDir":"/tmp"},"kind":"other","locations":[]},"options":[{"optionId":"once","kind":"allow_once","name":"Allow once"},{"optionId":"always","kind":"allow_always","name":"Always allow"},{"optionId":"reject","kind":"reject_once","name":"Reject"}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"...","update":{"sessionUpdate":"tool_call_update","toolCallId":"toolu_01Pi2R6Ko5TVVAX9SsWw1qe2","status":"in_progress","kind":"edit","title":"write","locations":[{"path":"/tmp/dummy-test-primary.txt"}],"rawInput":{"filePath":"/tmp/dummy-test-primary.txt","content":"hello from primary agent\n"}}}}

Same pattern for bash permission:

{"jsonrpc":"2.0","id":1,"method":"session/request_permission","params":{"sessionId":"...","toolCall":{"toolCallId":"toolu_016wFeFwJnkF5i8CzbknBbaz","status":"pending","title":"bash","rawInput":{},"kind":"execute","locations":[]},"options":[...]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"...","update":{"sessionUpdate":"tool_call_update","toolCallId":"toolu_016wFeFwJnkF5i8CzbknBbaz","status":"in_progress","kind":"execute","title":"bash","locations":[],"rawInput":{"command":"opencode --version 2>/dev/null || which opencode 2>/dev/null","description":"Get OpenCode version"}}}}

Expected behavior

The tool call should remain status: "pending" until the ACP client responds to session/request_permission. Only after receiving the permission response with allow_once/allow_always should the status transition to in_progress.

Impact

This confuses ACP clients (e.g. agent-shell) — the permission dialog gets overwritten before the user can respond, causing the tool call to hang indefinitely.

Environment

macOS, Emacs 30.2 (agent-shell via ACP), OpenCode v1.2.6

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions