Skip to content

desktop: Browser launcher disappears from the new tab view until app restart #60023

Closed

Description

@opencode-agent

What happened

Desktop, up to date with the current release (v2.2.0), session on the built-in server. The browser had been in use in the session: a page stopped loading, and afterwards the side panel's new-tab view showed only Review / Terminal / Open file. The Browser launcher was gone and did not come back. Quitting and reopening the app restored it.

Why it can't recover

The launcher (MenuItem in packages/gui-plugins/src/browser/renderer.tsx) shows only when model.available(view) && model.attached(view). The browser model in this window has terminal states that stay in place until the renderer reloads, and each of them hides the launcher:

  1. Server flagged unsupported. In pane.ts, if the attach stream fails with rpc.unavailable / rpc.method_not_found / rpc.invalid_input before the first attached control message, the reason becomes browser.pane.unsupported. model.ts then sets state.unsupported[server.id] = true, and connection.ts sets blocked = true. After that, available() is false for every session on that server in the window, so both the launcher and the browser.open command (⌃⌘B) are disabled. On the built-in server, rpc.unavailable can be transient: core/src/rpc.ts returns it while a location's registration is missing or was closed by routing-cache invalidation. A reconnect that lands in that window permanently marks a server that supports the browser as unsupported.
  2. browser.pane.replaced. When another attachment takes over the session (another desktop window, or any attach that wins the race), connection.ts sets blocked = true and state.browser = null, so attached() becomes false and the launcher disappears. Nothing in this window ever registers again.
  3. Suspended before the first inventory. suspend() keeps state.browser. If that is still null when the pane suspends, attached() is false and the launcher disappears, even though opening it is exactly what would wake the pane. Only session activity or ⌃⌘B can bring it back.

We don't know which of these paths this report hit (it was cleared by relaunching before we could check ⌃⌘B's error text). Paths 1 and 2 both leave the window stuck until the app restarts.

Expected

  • A transient rpc.unavailable from the built-in server (or any server that has the browser plugin) should not mark the server unsupported. Reserve unsupported for a definitive missing RPC/method, or retry with backoff and re-probe on reconnect or location change.
  • A replaced window should be able to take control back, at least when the user explicitly opens the browser, instead of being blocked for the rest of the window's life.
  • The new-tab launcher should not depend on attached(). It is itself a way to wake or reconnect the pane, so show it whenever available() is true and let opening it register.

Environment

  • OpenCode Desktop v2.2.0 (macOS), built-in server
  • Observed 2026-10-28 ~20:50 UTC

Activity

  1. evachxji commented on Oct 29, 2026

    @evachxji

    I reproduced the detached-pane launcher case and have a focused fix with regression coverage. I'll open a PR targeting dev.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.0bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions