tonhowtf/omniget · error

[omnidisc] could not subscribe to voice events

Error message

[omnidisc] could not subscribe to voice events

What it means

The voice store's init awaits listen("omnidisc://voice"); if that subscription call itself rejects, `initialized` is reset to false, this warning is logged, and init aborts early — the dispatch-channel subscription and initial status fetch never run. Voice features are effectively unavailable for the session.

Solutions

  1. Only run the voice store init inside a real Tauri runtime; gate with an isTauri check.
  2. Retry the subscription with backoff, or surface a disabled-voice UI state when initialized stays false.
  3. Ensure the Rust setup registers/emits the `omnidisc://voice` topic before the frontend boots.
  4. Make init idempotent to avoid a second init racing and resetting initialized.

Example fix

// before
await initVoice();
// after
if (!isTauri()) return;
await initVoice();
if (!initialized) showVoiceUnavailable();
Defensive patterns

Strategy: retry

Validate before calling

if (!('__TAURI_INTERNALS__' in window)) { markVoiceUnavailable(); return; }

Type guard

export function isTauri(): boolean {
  return typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;
}

Try / catch

try {
  unlisten = await listen<VoiceEventPayload>("omnidisc://voice", onVoiceEvent);
} catch (e) {
  initialized = false;
  console.warn("[omnidisc] could not subscribe to voice events", errorText(e));
  await retryWithBackoff(subscribeVoice, { attempts: 3 });
  return;
}

Prevention

When it happens

Trigger: Calling the voice init while the Tauri event/IPC layer is unavailable (non-Tauri runtime, premature call before webview ready), or a backend that never registers the `omnidisc://voice` event channel.

Common situations: Tests or Storybook rendering components that init the store outside a Tauri window; init called twice with a race resetting `initialized`; app started before the Rust setup hook registered events.

Related errors


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

Appendix: source

Thrown at src/lib/stores/omnidisc-voice-store.svelte.ts:492

    stats = null;
  }
}

export async function initVoice(): Promise<void> {
  loadVolumes();
  if (initialized) return;
  initialized = true;
  try {
    unlisten = await listen<VoiceEventPayload>("omnidisc://voice", (event) => {
      try {
        handleEvent(event.payload);
      } catch (e) {
        console.warn("[omnidisc] voice event failed", errorText(e));
      }
    });
  } catch (e) {
    initialized = false;
    console.warn("[omnidisc] could not subscribe to voice events", errorText(e));
    return;
  }
  try {
    unlistenDispatch = await listen<DispatchPayload>("omnidisc://dispatch", (event) => {
      try {
        handleDispatch(event.payload);
      } catch (e) {
        console.warn("[omnidisc] call ring failed", errorText(e));
      }
    });
  } catch (e) {
    console.warn("[omnidisc] could not subscribe to call rings", errorText(e));
  }
  try {
    applyStatus(await invoke<VoiceStatusWire>("omnidisc_voice_status"));
  } catch {
    return;
  }

View on GitHub (pinned to 8600b91f42)