fix(server): full-access OpenCode threads no longer ask for approvals - #9282
fix(server): full-access OpenCode threads no longer ask for approvals#9282shivamhwp wants to merge 4 commits into
Conversation
OpenCode ignores the session ruleset for doom-loop checks and drops the parent's wildcard allow when it spawns subagent sessions, so full-access threads still surfaced approval dialogs for those asks. Auto-reply "always" to any permission ask while the session is in full access and swallow the matching replied event, falling back to the dialog if the reply call fails. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ApprovabilityVerdict: Would Approve Macroscope's review found this PR approvable — This is a focused OpenCode bug fix that makes already-selected full-access sessions consistently auto-answer permission prompts while preserving approval-required behavior, with targeted coverage for parent, child, and failure paths. A Medium race finding remains separately recorded regarding stale approvals after terminal replies. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
A retry or recovery fiber could re-enter the pending-request path, or the matching permission.replied could land, while the auto-reply SDK call was still in flight. That raced to emit a duplicate request.opened or a stray request.resolved. Record the resolved and auto-replied ids synchronously before awaiting, and roll them back if the reply fails. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
| // The reply failed, so fall back to surfacing the approval. Undo | ||
| // the bookkeeping so the terminal event and any retry treat it as | ||
| // a normal pending request. | ||
| context.resolvedRequestIds.delete(request.id); |
There was a problem hiding this comment.
🟡 Medium Layers/OpenCodeAdapter.ts:1645
A failed in-flight auto-reply can emit request.opened after a matching permission.replied was already processed, leaving the UI with an approval for a request that is terminal and cannot be answered. The terminal handler records the request in emittedTerminalRequestIds, but the failure path at this point unconditionally removes the bookkeeping and falls through to emit the stale request; return early when that terminal marker is present.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/OpenCodeAdapter.ts around line 1645:
A failed in-flight auto-reply can emit `request.opened` after a matching `permission.replied` was already processed, leaving the UI with an approval for a request that is terminal and cannot be answered. The terminal handler records the request in `emittedTerminalRequestIds`, but the failure path at this point unconditionally removes the bookkeeping and falls through to emit the stale request; return early when that terminal marker is present.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 291c0dd. Configure here.
… resolved If the auto-reply SDK call fails locally but OpenCode still resolved the permission, the terminal permission.replied lands and is swallowed while the reply is in flight, consuming the terminal slot. The failure path then rolled back and opened a dialog that could never resolve. Guard the fallback: if the terminal event already landed, keep the request resolved and do not reopen it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Guard against a regression where the fallback retries the reply instead of surfacing the dialog. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

A user reported that OpenCode threads set to full access still pop approval dialogs. I reproduced it live against OpenCode 1.18.26 with a ChatGPT subscription. Ordinary tool calls are fine, but two paths in OpenCode ignore the session-level allow we send:
*.envor hitting any agent default prompts. Since fix(opencode): handle child approvals, stops, and model catalogs #8480 routes child asks to the thread, this also shows a dialog.Both are upstream OpenCode behavior, and full access means the user already said yes. The adapter now answers "always" to any permission ask that arrives while the session is in full access, and swallows the matching replied event so nothing reaches the UI. If the reply call fails, it falls back to showing the approval as before. Other modes are untouched.
Tests cover the doom-loop ask on the parent session, a child-session ask, and the failed-reply fallback.
Work done by Claude Fable 5.1 via Claude Code.
🤖 Generated with Claude Code
Note
Medium Risk
Changes permission handling for full-access OpenCode sessions only, but auto-approving without user confirmation increases blast radius if mis-gated; approval-required and other modes are unchanged.
Overview
Fixes full-access OpenCode threads still showing approval dialogs when upstream ignores the session wildcard (doom-loop detection and child/subagent sessions).
In
OpenCodeAdapter,permission.askedwhileruntimeMode === "full-access"now callspermission.replywithalwaysbefore emitting UI events. Matchingpermission.repliedevents are suppressed viaautoRepliedRequestIdssorequest.opened/request.resolvednever reach the client. Request ids are marked resolved before the async reply to avoid races with retries and duplicate dialogs.If the auto-reply fails, behavior falls back to surfacing the approval (single attempt, no retry loop), with extra guards when a terminal reply already landed during the in-flight SDK call.
Tests add a mock
permissionReplyImplementationhook and cover parent doom-loop asks, child-session asks, and failed-reply fallback.Reviewed by Cursor Bugbot for commit 5226415. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix full-access
OpenCodeAdapterthreads to skip approval promptsAdds integration tests that verify full-access OpenCode sessions auto-reply to permission requests with
alwaysinstead of surfacing user approval events. Covers parent-session doom-loop asks, child-session asks, and the fallback path where a failed auto-reply emits arequest.openedevent. UpdatesOpenCodeRuntimeTestDouble.permission.replyto support an injectable async hook so tests can simulate both success and failure of the auto-reply.Macroscope summarized 291c0dd.