-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
[Bug]: macOS Dashboard window keeps a dead SSH tunnel port after tunnel restart (remote mode) #100476
Copy link
Copy link
Closed
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.bugSomething isn't workingSomething isn't workingclawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper 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 does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.User-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.Very strong issue quality with high-confidence source-level or clear reproduction.maintainerMaintainer-authored PRMaintainer-authored PRmaturity:stableIssue affects a taxonomy feature currently scored M4/M5.Issue affects a taxonomy feature currently scored M4/M5.
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.bugSomething isn't workingSomething isn't workingclawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper 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 does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.User-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.Very strong issue quality with high-confidence source-level or clear reproduction.maintainerMaintainer-authored PRMaintainer-authored PRmaturity:stableIssue affects a taxonomy feature currently scored M4/M5.Issue affects a taxonomy feature currently scored M4/M5.
Type
Fields
Priority
None yet
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 andRemoteTunnelManagerrecreates it,RemotePortTunnel.createpicks a fresh ephemeral local port,GatewayEndpointStorepublishes 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/DashboardWindowControllersubscribes toGatewayEndpointStore.subscribe(); the URL+auth are only refreshed when the user manually re-opens the dashboard (DashboardManager.show()re-resolves the config).Steps to reproduce
gateway.mode: "remote"with SSH transport; open the Dashboard window (WebView URL ishttp://127.0.0.1:<ephemeralPort>/when the preferred port is taken).ssh -N -Ltunnel process (or sleep the Mac past ServerAliveCountMax so ssh exits).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
gatewayUrlto 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
apps/macos/Sources/OpenClaw/DashboardManager.swift(show()),apps/macos/Sources/OpenClaw/DashboardWindowController.swift(installNativeAuthScript, origin-pinned).apps/macos/Sources/OpenClaw/RemotePortTunnel.swift(findPort,allowRandomLocalPort: true),apps/macos/Sources/OpenClaw/RemoteTunnelManager.swift.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.