tonhowtf/omniget · warning

[omnidisc] stream volume failed

Error message

[omnidisc] stream volume failed

What it means

setStreamVolume invokes `omnidisc_stream_set_volume` with a gain clamped to [0, 2]. If the backend rejects (unknown user, no active audio sink for that user, command panic), the warning is logged and the volume simply is not applied. No state changes occur in the catch path.

Solutions

  1. Guard the call: only invoke when the backend reports the user as watched (check stream stats or watchingIds and a live-sink flag).
  2. Validate gain is a finite number before clamping: Number.isFinite(gain).
  3. Re-apply volume after watch completes (retry once the stream is established).
  4. Inspect the backend error to confirm the audio sink exists for that userId.

Example fix

// before
await invoke("omnidisc_stream_set_volume", { userId, gain: Math.min(2, Math.max(0, gain)) });
// after
if (!Number.isFinite(gain)) return;
await invoke("omnidisc_stream_set_volume", { userId, gain: Math.min(2, Math.max(0, gain)) });
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isFinite(gain) || gain < 0 || gain > 2) return;
if (!watchingIds.includes(userId)) return;

Type guard

function isValidGain(g: unknown): g is number {
  return typeof g === 'number' && Number.isFinite(g) && g >= 0 && g <= 2;
}

Try / catch

try {
  await invoke("omnidisc_stream_set_volume", { userId, gain: clamp(gain, 0, 2) });
} catch (e) {
  console.warn("[omnidisc] stream volume failed", errorText(e));
  scheduleVolumeRetry(userId, gain); // re-apply once stream is live
}

Prevention

When it happens

Trigger: Calling setStreamVolume(userId, gain) for a userId with no active watched stream/audio element in the backend, a NaN gain (NaN bypasses min/max clamping), or a backend that has torn down the audio sink for that peer.

Common situations: Moving a volume slider while the remote stream just ended; volume applied before the watch handshake completes; NaN produced by an uncontrolled input parsed to a number.

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

Appendix: source

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

    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;
  } catch {
    return null;
  }
}

interface StreamEventPayload {
  type: string;
  audio?: AudioMode;
  user_id?: string;
  active?: boolean;

View on GitHub (pinned to 8600b91f42)