-
-
Notifications
You must be signed in to change notification settings - Fork 67
Description
Describe the bug
The suspend/resume connection logic fails to reconnect after the browser tab/window has been hidden for more than 5 minutes. The visibilitychange event to visible does not always fire when returning to the page, causing the resume logic (onVisibleOrResume()) to never trigger. The connection attempts to reconnect but fails repeatedly with error code 3, leaving the dashboard stuck showing "Connection lost. Reconnecting..." indefinitely.
To Reproduce
Steps to reproduce the behavior:
- Load a hakit React dashboard in a browser (tested with both direct panel URL and ingress URL)
- Enable debug logging in HassConnect:
<HassConnect
hassUrl="http://homeassistant.local:8123"
options={{
handleResumeOptions: {
debug: true,
onStatusChange(status) {
console.log("[HassConnect] Connection status changed:", status, new Date().toISOString());
},
},
}}
>
- Wait for connection to establish (see
[HassConnect] Connection status changed: connectedin console) - Either:
- Switch to a different browser tab, OR
- Minimize the browser window to taskbar
- Wait 6-8 minutes (longer than the default 5 minute
hiddenDelayMs) - Return to the dashboard tab/window
- Observe "Connection lost. Reconnecting..." message that never resolves
Expected behavior
When returning to the page:
visibilitychange → VISIBLEevent should fireonVisibleOrResume()should triggerpendingResolve()should be called to lift suspension- Connection should successfully reconnect
Screenshots / code examples
Successful reconnection (visibilitychange fired correctly)
[HassConnect] Connection status changed: pending 2026-02-06T12:07:44.323Z
[SR] Connection is already active → handleSuspendResume will manage suspension
[HassConnect] Connection status changed: connected 2026-02-06T12:07:44.335Z
[SR] handleSuspendResume() initialized; debugging is ON
[SR] visibilitychange → HIDDEN
[SR] onHidden() triggered
[SR] Calling connection.suspendReconnectUntil(...)
[HassConnect] Connection status changed: pending-suspension 2026-02-06T12:08:07.609Z
[SR] Starting hidden delay of 300000ms before actual suspend()
[SR] Hidden timeout elapsed → calling suspend()
[SR] Connection already suspended → skipping suspend()
[SR] visibilitychange → VISIBLE
[SR] onVisibleOrResume() fired (page became visible)
[SR] Resolving pendingResolve() on actual resume
[SR] pendingResolve() called → lifting suspension
[HassConnect] Connection status changed: connected 2026-02-06T12:14:30.356Z
Failed reconnection (visibilitychange never fired)
[HassConnect] Connection status changed: pending 2026-02-06T12:47:54.272Z
[SR] Connection is already active → handleSuspendResume will manage suspension
[HassConnect] Connection status changed: connected 2026-02-06T12:47:54.291Z
[SR] handleSuspendResume() initialized; debugging is ON
[SR] visibilitychange → HIDDEN
[SR] onHidden() triggered
[SR] Calling connection.suspendReconnectUntil(...)
[HassConnect] Connection status changed: pending-suspension 2026-02-06T12:48:12.815Z
[SR] Starting hidden delay of 300000ms before actual suspend()
[HassConnect] Connection status changed: pending 2026-02-06T12:56:00.673Z
subscribeUsers: failed to fetch users 3
Uncaught (in promise) 3
Uncaught (in promise) 3
Uncaught (in promise) 3
Uncaught (in promise) 3
Note: NO [SR] visibilitychange → VISIBLE event appears in the failed case.
System Info:
IDE: Visual Studio Code
Browser: Microsoft Edge Version 144.0.3719.115 (Official build) (64-bit)
npm version: 11.6.4
node version: 24.13.0
Installation method: Home Assistant OS
HA Core: 2026.1.3
Supervisor: 2026.01.1
Operating System: 16.3
Frontend: 20260107.2
@hakit/core version: 6.0.1
@hakit/components version: 6.0.1
Additional context
The dashboard is served via panel_custom which loads it in an iframe
The iframe sandbox warning appears in console: An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.
Error code 3 in home-assistant-js-websocket typically indicates authentication/connection failure
The issue appears to be browser-dependent behavior where visibilitychange doesn't fire when the browser resumes a frozen/suspended tab