Summary
When the SSH tunnel process exits unexpectedly, SshTunnelService only logs a warning. It does not clean up _process/_lastSpec, does not raise any event, and does not attempt a restart. The gateway client keeps reconnecting to ws://127.0.0.1:<localPort> which is now unreachable.
Location
src/OpenClaw.Tray.WinUI/Services/SshTunnelService.cs lines ~123-134 (process.Exited handler)
Impact
If the SSH tunnel crashes, the entire remote connectivity feature is broken until the user manually intervenes (e.g., changes settings or restarts the app). The reconnect loop will spin forever against a dead localhost port.
Flagged by
Multi-model code review consensus (2/3 models: Opus, GPT-5.4)
Suggested Fix
- Null out
_process and _lastSpec in the Exited handler so the next EnsureStarted call creates a fresh tunnel
- Expose a
TunnelExited event that App subscribes to for triggering automatic tunnel restart and gateway reconnect
- Consider a bounded retry with backoff for automatic tunnel restart
Summary
When the SSH tunnel process exits unexpectedly,
SshTunnelServiceonly logs a warning. It does not clean up_process/_lastSpec, does not raise any event, and does not attempt a restart. The gateway client keeps reconnecting tows://127.0.0.1:<localPort>which is now unreachable.Location
src/OpenClaw.Tray.WinUI/Services/SshTunnelService.cslines ~123-134 (process.Exitedhandler)Impact
If the SSH tunnel crashes, the entire remote connectivity feature is broken until the user manually intervenes (e.g., changes settings or restarts the app). The reconnect loop will spin forever against a dead localhost port.
Flagged by
Multi-model code review consensus (2/3 models: Opus, GPT-5.4)
Suggested Fix
_processand_lastSpecin theExitedhandler so the nextEnsureStartedcall creates a fresh tunnelTunnelExitedevent thatAppsubscribes to for triggering automatic tunnel restart and gateway reconnect