tonhowtf/omniget · warning

[player] failed saving spotify heartbeat_interval_ms

Error message

[player] failed saving spotify heartbeat_interval_ms

What it means

A non-fatal console warning emitted by MusicPlayerStore when persisting the Spotify heartbeat interval to the backend via pluginInvoke('study','study:music:spotify:settings:set') throws. The in-memory value (_spotifyHeartbeatMs) was already applied, so the player keeps working with the new interval but it will not survive a restart.

Solutions

  1. Check the backend 'study' plugin is registered and the command study:music:spotify:settings:set exists in the installed version
  2. Inspect the caught error for an IPC/plugin-not-found cause and restart the app so the plugin initializes before changing the interval
  3. Fix filesystem permission/disk issues preventing settings persistence
  4. Retry the save once the backend is available; the value is already applied in memory

Example fix

// before
await pluginInvoke("study", "study:music:spotify:settings:set", { heartbeat_interval_ms: clamped });
// after
if (await isPluginCommandAvailable("study", "study:music:spotify:settings:set")) {
  await pluginInvoke("study", "study:music:spotify:settings:set", { heartbeat_interval_ms: clamped });
} else {
  queueSettingsSave({ heartbeat_interval_ms: clamped }); // retry once backend is up
}
Defensive patterns

Strategy: try-catch

Validate before calling

const ok = typeof ms === "number" && ms >= 1000 && ms <= 60000;

Type guard

function isFiniteMs(v: unknown): v is number { return typeof v === "number" && Number.isFinite(v) && v > 0; }

Try / catch

try { await pluginInvoke("study", "study:music:spotify:settings:set", { heartbeat_interval_ms: clamped }); } catch (e) { console.warn("save deferred", e); pendingSaves.push(() => pluginInvoke("study", "study:music:spotify:settings:set", { heartbeat_interval_ms: clamped })); }

Prevention

When it happens

Trigger: Calling the Spotify heartbeat interval setter while the Tauri 'study' plugin command study:music:spotify:settings:set rejects — e.g. plugin backend not running, settings file write failure, or IPC serialization error.

Common situations: App started before the study plugin backend initialized; disk-full or permission problems on the settings file; an older backend version that does not implement the spotify settings command.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

      this.stopSpotifyHeartbeat();
    }
  }

  async setSpotifyHeartbeatIntervalMs(ms: number) {
    const clamped = Math.min(
      MusicPlayerStore.SPOTIFY_HEARTBEAT_MAX_MS,
      Math.max(
        MusicPlayerStore.SPOTIFY_HEARTBEAT_MIN_MS,
        Math.floor(Number(ms) || 30_000),
      ),
    );
    this._spotifyHeartbeatMs = clamped;
    try {
      await pluginInvoke("study", "study:music:spotify:settings:set", {
        heartbeat_interval_ms: clamped,
      });
    } catch (e) {
      console.warn("[player] failed saving spotify heartbeat_interval_ms", e);
    }
    if (this._spotifyHeartbeatHandle) {
      this.stopSpotifyHeartbeat();
      if (this.isSpotify() && this._spotifyIsPlaying) this.startSpotifyHeartbeat();
    }
  }

  getSpotifyHeartbeatEnabled(): boolean {
    return this._spotifyHeartbeatEnabled;
  }

  getSpotifyHeartbeatIntervalMs(): number {
    return this._spotifyHeartbeatMs;
  }

  private static clampRpcInterval(ms: number): number {
    return Math.min(
      MusicPlayerStore.RPC_UPDATE_INTERVAL_MAX_MS,

View on GitHub (pinned to 8600b91f42)