Skip to content

Windows Desktop: SSE event stream silently drops, UI stops updating (requires Ctrl+R to refresh) #13655

Closed

Description

@brunusansi

Bug Description

On Windows Desktop, the SSE (Server-Sent Events) connection between the WebView2 frontend and the local sidecar server silently drops during use. When this happens, the UI stops receiving realtime updates — messages are processed by the backend but the UI doesn't reflect them. The only workaround is pressing Ctrl+R to force a page reload, which re-establishes the SSE connection.

Root Cause Analysis

After tracing through the source code, I identified the issue in packages/app/src/context/global-sdk.tsx:

const eventFetch = (() => {
  if (!platform.fetch) return
  try {
    const url = new URL(server.url)
    const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '::1'
    if (url.protocol === 'http:' && !loopback) return platform.fetch
  } catch {
    return
  }
})()

For desktop connections (always localhost):

  • loopback evaluates to true
  • The condition url.protocol === 'http:' && !loopback is false
  • eventFetch returns undefined
  • The SSE stream falls back to WebView2's native fetch instead of Tauri's platform.fetch

WebView2's native fetch has known reliability issues with long-lived SSE connections on localhost. The connection drops silently, and while the reconnection loop (RECONNECT_DELAY_MS = 250ms) attempts to re-establish it, the same underlying issue causes repeated failures.

The SSE heartbeat in server.ts is set to 30 seconds with a comment referencing WKWebView's 60-second timeout — but WebView2 on Windows has different behavior that this heartbeat doesn't address.

Suggested Fix

Force platform.fetch (Tauri's native HTTP client) for SSE connections on localhost when running in the desktop app:

const eventFetch = (() => {
  if (!platform.fetch) return
  try {
    const url = new URL(server.url)
    const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '::1'
    // Use platform.fetch for ALL connections in desktop mode,
    // including loopback, to avoid WebView2 SSE reliability issues
    if (url.protocol === 'http:') return loopback ? platform.fetch : platform.fetch
  } catch {
    return
  }
})()

Or more simply, always return platform.fetch when available:

const eventFetch = platform.fetch ?? undefined

This would bypass WebView2's native fetch entirely for the SSE stream and use Tauri's HTTP plugin, which doesn't suffer from the same connection dropping behavior.

Workaround

Setting WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS environment variable before launching the app mitigates the issue:

WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--disable-background-timer-throttling --disable-renderer-backgrounding --disable-features=IntensiveWakeUpThrottling,BackForwardCache --disable-http2

Environment

  • OS: Windows 10/11
  • OpenCode Desktop: v1.2.2
  • Frequency: Every session, from the start — not intermittent

Related Issues

Activity

  1. github-actions commented on Apr 16, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 90 days of no activity. If the issue is still relevant please open a new one.

  2. konchetobe commented on May 18, 2026

    @konchetobe

    Seems to still be active even on v1.15.4

  3. pranshunotpriyanshu commented on Jul 4, 2026

    @pranshunotpriyanshu

    Seems to still be active even on v1.17.13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

webRelates to opencode on web / desktopwindows

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions