tonhowtf/omniget · warning

[omnidisc] unwatch failed

Error message

[omnidisc] unwatch failed

What it means

unwatchStream invokes `omnidisc_stream_unwatch` to stop receiving a user's stream. On backend rejection the warning is logged, but the finally block always removes the userId from `watchingIds`, so local state and backend state can diverge. Called from initStream, toggleWatch, and stop (which unwatch all ids during teardown).

Solutions

  1. Make the backend unwatch idempotent (no-op + Ok when the id is unknown).
  2. Filter the id from watchingIds before invoking, or reconcile backend watch state via a stats/refresh call after failure.
  3. Log errorText(e) server-side correlation: inspect the Rust error to see if it is 'not watching' vs command-missing.
  4. Deduplicate toggleWatch so unwatch is not issued twice concurrently.

Example fix

// before
await invoke("omnidisc_stream_unwatch", { userId });
// after
if (watchingIds.includes(userId)) {
  await invoke("omnidisc_stream_unwatch", { userId });
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!watchingIds.includes(userId)) return;

Try / catch

try {
  await invoke("omnidisc_stream_unwatch", { userId });
} catch (e) {
  console.warn("[omnidisc] unwatch failed", errorText(e));
} finally {
  watchingIds = watchingIds.filter((id) => id !== userId);
}

Prevention

When it happens

Trigger: Calling unwatchStream(userId) for a userId the backend is not watching, a malformed userId, or when the backend `omnidisc_stream_unwatch` command panics/is unregistered. Also fires during stop() teardown for every watched id.

Common situations: Backend already dropped the peer (stream ended server-side) so unwatch finds nothing; duplicate unwatch after a toggle race; stale watch entries after a reconnect.

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/a513e80982d4c866. Report an issue: GitHub.

Appendix: source

Thrown at src/lib/stores/omnidisc-stream-store.svelte.ts:289

  busy = true;
  lastError = null;
  try {
    await invoke("omnidisc_stream_watch", { userId });
    if (!watchingIds.includes(userId)) watchingIds = [...watchingIds, userId];
    return true;
  } catch (e) {
    lastError = errorText(e);
    return false;
  } finally {
    busy = false;
  }
}

export async function unwatchStream(userId: string): Promise<void> {
  try {
    await invoke("omnidisc_stream_unwatch", { userId });
  } catch (e) {
    console.warn("[omnidisc] unwatch failed", errorText(e));
  } finally {
    watchingIds = watchingIds.filter((id) => id !== userId);
  }
}

export async function setStreamVolume(userId: string, gain: number): Promise<void> {
  try {
    await invoke("omnidisc_stream_set_volume", { userId, gain: Math.min(2, Math.max(0, gain)) });
  } catch (e) {
    console.warn("[omnidisc] stream volume failed", errorText(e));
  }
}

export async function refreshStreamStats(): Promise<StreamStats | null> {
  try {
    stats = await invoke<StreamStats>("omnidisc_stream_stats");
    if (stats.publishing) publishing = stats.publishing;
    return stats;

View on GitHub (pinned to 8600b91f42)