jamiepine/voicebox · error · Error
System audio capture is only available in the desktop app.
Error message
System audio capture is only available in the desktop app.
What it means
Thrown by webAudio.startSystemAudioCapture() — the web platform stub of PlatformAudio. The browser cannot capture system/desktop audio (no equivalent to the Tauri desktop loopback), so this method is an unconditional throw. The companion isSystemAudioSupported() returns false and listOutputDevices() returns []; these are the supported capability probes a caller must check first.
Source
Thrown at web/src/platform/audio.ts:9
import type { PlatformAudio, AudioDevice } from '@/platform/types';
export const webAudio: PlatformAudio = {
async isSystemAudioSupported(): Promise<boolean> {
return false; // System audio capture not supported in web
},
async startSystemAudioCapture(_maxDurationSecs: number): Promise<void> {
throw new Error('System audio capture is only available in the desktop app.');
},
async stopSystemAudioCapture(): Promise<Blob> {
throw new Error('System audio capture is only available in the desktop app.');
},
async listOutputDevices(): Promise<AudioDevice[]> {
return []; // No native device routing in web
},
async playToDevices(_audioData: Uint8Array, _deviceIds: string[]): Promise<void> {
throw new Error('Native audio device routing is only available in the desktop app.');
},
stopPlayback(): void {
// No-op for web
},
};View on GitHub (pinned to 51f49dea19)
Solutions
- Gate the call behind isSystemAudioSupported() and disable the UI affordance when it returns false.
- Confirm the platform resolver injects the desktop audio implementation inside the Tauri build, not webAudio.
- Surface an in-app message directing the user to the desktop app for system-audio capture.
- Provide a web alternative (getUserMedia microphone capture) where system audio is not strictly required.
Example fix
// before
await platform.audio.startSystemAudioCapture(30);
// after
if (!(await platform.audio.isSystemAudioSupported())) {
toast({ title: 'System audio capture needs the desktop app.' });
return;
}
await platform.audio.startSystemAudioCapture(30); Defensive patterns
Strategy: validation
Validate before calling
async function canCaptureSystemAudio(audio: PlatformAudio): Promise<boolean> {
try {
return await audio.isSystemAudioSupported();
} catch {
return false;
}
}
// Guard every entry point:
if (!(await canCaptureSystemAudio(platform.audio))) {
toast({ title: 'System audio capture needs the desktop app.' });
return;
} Try / catch
if (!(await platform.audio.isSystemAudioSupported())) {
toast({ title: 'System audio capture is desktop-only.' });
return;
}
try {
await platform.audio.startSystemAudioCapture(30);
} catch (e) {
toast({ title: 'Capture failed', description: (e as Error).message, variant: 'destructive' });
} Prevention
- Always gate startSystemAudioCapture on isSystemAudioSupported().
- Inject the correct platform audio impl per build (webAudio for web, desktop impl for Tauri).
- Hide the system-audio UI affordance when the capability probe is false.
When it happens
Trigger: Code path running on the web build calls startSystemAudioCapture(maxDurationSecs) directly. This happens when platform-agnostic code forgets to gate on isSystemAudioSupported() or when the wrong platform implementation is injected (web build used where desktop was expected).
Common situations: A feature developed against the Tauri desktop build is exercised in the web build. The platform PlatformAudio binding falls back to webAudio because the desktop module wasn't bundled. A user opens the web UI expecting system-audio capture that only exists in the desktop app.
Related errors
- Native audio device routing is only available in the desktop
- Failed to resolve save path from dialog
- e instanceof Error ? e.message : errorMessage
- HTTP ${res.status}
- Jupiter HTTP ${res.status}
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/71b00279c9123ab0.
Report an issue: GitHub.