Repository navigation
Description
Bug Description
When the browser page is refreshed or reopened while an AI task is running, pending permission requests that were issued before the refresh are never auto-accepted, even when auto-accept is enabled. The task remains stuck waiting for a response that never comes, and no permission dialog is shown to the user.
Reproduction Steps
- Start a conversation with OpenCode in the web UI
- Send a message that triggers a permission request (e.g.,
git commit) - Before the permission dialog appears, close or refresh the browser page
- Reopen the page (auto-accept setting is restored from localStorage)
- Observe that:
- The auto-accept toggle shows as "enabled"
- The AI task is still running but appears stuck
- No permission dialog is visible
- The permission request is never auto-accepted
Expected Behavior
After page refresh, the app should:
- Query for any pending permission requests from the backend
- If auto-accept is enabled for that session/directory, automatically respond to pending permissions
- If auto-accept is disabled, show the permission dialog for pending requests
Actual Behavior
The pending permission requests are never processed because:
- SSE only delivers real-time events, not historical ones
- The
permission.askedevent was sent before the page reconnected - The auto-accept logic only triggers when receiving new
permission.askedevents - No code queries for pending permissions on page initialization
Root Cause Analysis
Looking at the code:
// packages/app/src/context/permission.tsx
const unsubscribe = globalSDK.event.listen((e) => {
const event = e.details
if (!e.name.startsWith("permission.")) return
const perm = event.properties
if (!shouldAutoRespond(perm, e.name)) return
respondOnce(perm, e.name)
})The auto-accept only works when the frontend receives a permission.asked event via SSE. However, SSE is a real-time stream - when the page disconnects and reconnects, previously sent events are not replayed.
The enable() function does query for pending permissions:
function enable(sessionID: string, directory: string) {
setStore(...)
globalSDK.client.permission
.list({ directory })
.then((x) => {
for (const perm of x.data ?? []) {
if (shouldAutoRespond(perm, directory)) {
respondOnce(perm, directory)
}
}
})
}But this is only called when the user manually toggles auto-accept. There's no equivalent logic on page initialization.
Proposed Fix
On page initialization (in permission.tsx), after the store is ready, query for pending permissions and process them according to the current auto-accept settings:
// In permission.tsx, after persisted store is ready
createEffect(() => {
if (!ready()) return
const directory = decode64(params.dir)
if (!directory) return
// Query and process pending permissions
globalSDK.client.permission
.list({ directory })
.then((x) => {
for (const perm of x.data ?? []) {
if (shouldAutoRespond(perm, directory)) {
respondOnce(perm, directory)
}
}
})
})Environment
- OpenCode version: Latest dev branch
- Browser: Any (Chrome, Safari, Firefox)
- OS: Any (macOS, Linux, Windows)
- UI: Web interface (packages/app)
Activity
hueyexe commentedon Jun 17, 2026
I am encountering this too. My set up is an opencode web server at home over a Tailscale VPN. I have the session open on my phone away from home, with auto accept permissions enabled. It runs fine until I change apps, my phone locks, and I assume the browser is put to sleep. When I come back to the page the session seems to be frozen on shell commands, but no pop up visible. Turing auto accept permissions off/on resumes the session again. Keeping the window open also seems to prevent it.
github-actions commentedon Aug 16, 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.