tonhowtf/omniget · warning

[player] spotify heartbeat resync failed

Error message

[player] spotify heartbeat resync failed

What it means

Non-fatal warning: the periodic Spotify heartbeat failed to resync local player state with the Web Playback SDK (spotifySdk.getCurrentState() threw), so the UI may temporarily show stale playback state.

Solutions

  1. Verify the Spotify SDK/player is initialized before starting the heartbeat
  2. Check network/session state; re-authenticate or reconnect the Spotify player if needed
  3. Guard the resync: skip if SDK is not ready
  4. Increase heartbeat interval to reduce SDK pressure

Example fix

// before
const state = await spotifySdk.getCurrentState();
// after
if (!spotifySdk.isReady()) return;
const state = await spotifySdk.getCurrentState();
if (!state) return;
this.applySpotifyState(state);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!this._spotifyPlayerReady || !this._spotifyConnected) return;

Type guard

function hasSpotifyState(s: unknown): s is SpotifyPlaybackState {
  return !!s && typeof s === "object" && "track_window" in s;
}

Try / catch

try {
  const state = await spotifySdk.getCurrentState();
  if (state) this.applySpotifyState(state);
} catch (e) {
  console.warn("[player] spotify heartbeat resync failed", e);
  if (++this._resyncFailures > 3) this.reconnectSpotify();
}

Prevention

When it happens

Trigger: spotifySdk.getCurrentState() rejects or the SDK is not yet initialized when the heartbeat timer fires spotifyResyncFromSdk().

Common situations: Spotify Web SDK not loaded/connected yet, browser suspended the tab/SDK, Spotify session dropped, or heartbeat firing before player readiness.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/3c67662d9d62fa46. Report an issue: GitHub.

Appendix: source

Thrown at src/lib/study-music/player-store.svelte.ts:722

    this._spotifyHeartbeatHandle = setInterval(() => {
      if (!this.isSpotify()) return;
      void this.spotifyResyncFromSdk();
    }, intervalMs);
  }

  private stopSpotifyHeartbeat() {
    if (this._spotifyHeartbeatHandle) {
      clearInterval(this._spotifyHeartbeatHandle);
      this._spotifyHeartbeatHandle = null;
    }
  }

  private async spotifyResyncFromSdk() {
    try {
      const state = await spotifySdk.getCurrentState();
      if (state) this.applySpotifyState(state);
    } catch (e) {
      console.warn("[player] spotify heartbeat resync failed", e);
    }
  }

  private async loadSpotifySettings() {
    if (this._spotifySettingsLoaded) return;
    this._spotifySettingsLoaded = true;
    try {
      const res = await pluginInvoke<{
        heartbeat_enabled?: boolean;
        heartbeat_interval_ms?: number;
      }>("study", "study:music:spotify:settings:get", {});
      this._spotifyHeartbeatEnabled = res?.heartbeat_enabled ?? true;
      const ms = Number(res?.heartbeat_interval_ms ?? 30_000);
      this._spotifyHeartbeatMs = Number.isFinite(ms)
        ? Math.min(
            MusicPlayerStore.SPOTIFY_HEARTBEAT_MAX_MS,
            Math.max(MusicPlayerStore.SPOTIFY_HEARTBEAT_MIN_MS, ms),
          )

View on GitHub (pinned to 8600b91f42)