Skip to content

[Bug]: macOS Dashboard window keeps a dead SSH tunnel port after tunnel restart (remote mode) #100476

Description

@steipete

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

In remote (SSH) mode, the macOS app's Dashboard window bakes the forwarded tunnel's local port into the WebView at open time — both the page URL and the injected __OPENCLAW_NATIVE_CONTROL_AUTH__.gatewayUrl (DashboardWindowController.installNativeAuthScript). When the SSH tunnel later dies and RemoteTunnelManager recreates it, RemotePortTunnel.create picks a fresh ephemeral local port, GatewayEndpointStore publishes the new endpoint — but the already-open WebView never learns about it. Its reconnect loop hammers the dead old port forever and the Control UI drops to the connect gate with "Could not connect" (ws://127.0.0.1:<dead-port>/).

Nothing in DashboardManager/DashboardWindowController subscribes to GatewayEndpointStore.subscribe(); the URL+auth are only refreshed when the user manually re-opens the dashboard (DashboardManager.show() re-resolves the config).

Steps to reproduce

  1. gateway.mode: "remote" with SSH transport; open the Dashboard window (WebView URL is http://127.0.0.1:<ephemeralPort>/ when the preferred port is taken).
  2. Kill the app's ssh -N -L tunnel process (or sleep the Mac past ServerAliveCountMax so ssh exits).
  3. Trigger anything that re-ensures the tunnel (menu health check) — a new tunnel appears on a different local port.
  4. The open Dashboard window shows the login gate with "Could not connect" permanently; reopening the window from the menu fixes it.

Expected behavior

The dashboard window observes the endpoint store; when the resolved control endpoint changes while the window is open, it re-injects auth for the new origin and reloads the WebView (or better: hands the new gatewayUrl to the running page so the web app can reconnect without a reload).

Actual behavior

Open window keeps the dead port until manually reopened.

OpenClaw version

main @ 5fdaa04

Operating system

macOS 26.5 (Apple Silicon)

Install method

git checkout (dev build)

Model

n/a

Provider / routing chain

n/a

Additional provider/model setup details

n/a

Logs

Live repro observed: WebView pinned to ws://127.0.0.1:51206/ (dead), while the app's live tunnel was -L 51215:127.0.0.1:18789 (pid child of the running app). Remote gateway healthy (HTTP 200 through the live tunnel).

Screenshots, recordings, and evidence

  • URL/auth baked at open time: apps/macos/Sources/OpenClaw/DashboardManager.swift (show()), apps/macos/Sources/OpenClaw/DashboardWindowController.swift (installNativeAuthScript, origin-pinned).
  • Fresh ephemeral port per tunnel restart: apps/macos/Sources/OpenClaw/RemotePortTunnel.swift (findPort, allowRandomLocalPort: true), apps/macos/Sources/OpenClaw/RemoteTunnelManager.swift.
  • Endpoint changes are published but unobserved by the dashboard: apps/macos/Sources/OpenClaw/GatewayEndpointStore.swift (subscribe, setState).

Impact and severity

Remote-mode users get a permanently dead dashboard window after any tunnel churn (sleep/wake is enough); reads as "app broken". Medium-high UX impact, no data loss.

Additional information

Compounded by tunnel-port instability when the preferred local port is occupied: #100477. Web-side graceful degradation: #100475. The web-side graceful-reconnect banner reduces the blast radius but cannot fix a stale endpoint by itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.bugSomething isn't workingclawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maintainerMaintainer-authored PRmaturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions