You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a child session (subagent) triggers a permission request in the Web UI, approving it via "Allow once" or "Allow always" can leave the permission prompt visible in the composer even after the server has accepted the response.
The server returns 200 true for the permission reply, and subsequent GET /permission calls return an empty array [], confirming the permission was processed. However, the Web UI composer still renders the stale permission prompt until another sync event arrives or the page is refreshed.
Steps to Reproduce
Start OpenCode with Web UI (opencode serve and opencode attach, or dev mode).
Create a session and trigger a subagent or background task that requires a permission (e.g., a bash command with permission: { bash: "ask" }).
In the parent session composer, observe the permission prompt for the child session.
Click "Allow once".
Observe that the permission prompt remains visible in the composer, even though the subagent proceeds.
Expected Behavior
The permission prompt should be removed from the composer immediately after the server confirms the response.
Actual Behavior
The permission prompt persists in the Web UI composer, creating a stale UI state that may confuse users.
Environment
OpenCode version: latest (observed during development)
Browser: Chrome (via Chrome DevTools MCP during reproduction)
OS: Linux
Related
This is a client-side UI state issue. The backend processes the permission correctly, but the frontend sync cache does not remove the accepted permission from the local store after a successful response.
Proposed Fix
After sdk.client.permission.respond() succeeds, optimistically remove the matching permission from the local sync cache (sync.set("permission", sessionID, ...)) so the composer re-renders without the stale prompt.
This aligns the UI state with the confirmed server response without waiting for the next sync event.
This is supposed to be handled by processing the permission.replied event from the backend, is it not being received or processed in your case?
Yes, the backend does publish permission.replied, and the app reducer already handles it.
The part that was missing was on the Web/Desktop approval path. After clicking approve, the UI was relying on that live event as the only thing that clears the already-rendered local permission prompt. In the nested child-session case, that prompt can come from local sync/list state, while the event may be delayed, missed during reconnect/bootstrap timing, or ignored if the child directory store is not mounted yet. Then the server has accepted the reply, but the composer can still keep showing the stale prompt until a later refresh reconciles it.
#28651 keeps the existing permission.replied handling, but also clears the matching local permission after permission.reply({ requestID }) succeeds. It also moves the Web/Desktop path off the deprecated session-scoped permission.respond call and onto the request-scoped reply endpoint, which matches the TUI/ACP/run paths.
I have witnessed the same symptoms, i.e. repeatedly asking for Permissions required. I could only select Allow Always, which gave me the choice of Confirm. It would immediately return me to the same Permissions required dialog. I could select (n)either Allow Once or Reject and it would return me immediately to the dialog, i.e. no change.
I started an opencode session in a folder ~/project/opencode
Later I restarted it in the parent folder ~/project
This is where the trouble started, because the current folder is now outside / the parent folder is external to the root folder of the continued session.
Opencode suggested me I should set/add "external_directory": "allow" in the ~/.config/opencode/opencode.jsonc but that defeats the directory permissions purpose.
I hope this report can help to reproduce and fix the issue also on your side ?
Activity
Brendonovich commentedon May 13, 2026
This is supposed to be handled by processing the
permission.repliedevent from the backend, is it not being received or processed in your case?donicrosby commentedon May 14, 2026
It is not causing the TUI and Webapp to constantly ask for permission even thought it's already been granted.
MingyooLee commentedon May 26, 2026
Yes, the backend does publish
permission.replied, and the app reducer already handles it.The part that was missing was on the Web/Desktop approval path. After clicking approve, the UI was relying on that live event as the only thing that clears the already-rendered local permission prompt. In the nested child-session case, that prompt can come from local sync/list state, while the event may be delayed, missed during reconnect/bootstrap timing, or ignored if the child directory store is not mounted yet. Then the server has accepted the reply, but the composer can still keep showing the stale prompt until a later refresh reconciles it.
#28651 keeps the existing
permission.repliedhandling, but also clears the matching local permission afterpermission.reply({ requestID })succeeds. It also moves the Web/Desktop path off the deprecated session-scopedpermission.respondcall and onto the request-scoped reply endpoint, which matches the TUI/ACP/run paths.stefan123t commentedon May 31, 2026
I have witnessed the same symptoms, i.e. repeatedly asking for Permissions required. I could only select Allow Always, which gave me the choice of Confirm. It would immediately return me to the same Permissions required dialog. I could select (n)either Allow Once or Reject and it would return me immediately to the dialog, i.e. no change.
I started an opencode session in a folder
~/project/opencodeLater I restarted it in the parent folder
~/projectThis is where the trouble started, because the current folder is now outside / the parent folder is external to the root folder of the continued session.
Opencode suggested me I should set/add
"external_directory": "allow"in the~/.config/opencode/opencode.jsoncbut that defeats the directory permissions purpose.I hope this report can help to reproduce and fix the issue also on your side ?
github-actions commentedon Jul 31, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.