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
- Only run the voice store init inside a real Tauri runtime; gate with an isTauri check.
- Retry the subscription with backoff, or surface a disabled-voice UI state when initialized stays false.
- Ensure the Rust setup registers/emits the `omnidisc://voice` topic before the frontend boots.
- 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
- Gate voice init on the Tauri runtime and on backend readiness.
- Retry the subscription with exponential backoff before giving up.
- Show an explicit voice-unavailable UI state when initialized stays false.
- Keep init single-flight; never let a concurrent call reset initialized.
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
- [omnidisc] stream events subscribe failed
- [omnidisc] voice event failed
- [omnidisc] call ring failed
- [omnidisc] could not subscribe to call rings
- [omnidisc] voice leave failed
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)