jamiepine/voicebox · error · Error
Microphone access is not available. Please ensure: 1. The ap
Error message
Microphone access is not available. Please ensure: 1. The app has microphone permissions in System Settings (macOS: System Settings > Privacy & Security > Microphone) 2. You restart the app after granting permissions 3. You are using Tauri v2 with a webview that supports getUserMedia
What it means
Thrown by `startRecording()` in `useAudioRecording.ts` (line 53-57) on the Tauri branch when `navigator.mediaDevices` or `getUserMedia` is still absent after a 100 ms wait. The message enumerates the macOS permission grant flow and the Tauri v2 requirement. `platform.metadata.isTauri` selects this branch.
Source
Thrown at app/src/lib/hooks/useAudioRecording.ts:57
}
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
// Try waiting a bit for Tauri webview to initialize
await new Promise((resolve) => setTimeout(resolve, 100));
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
console.error('MediaDevices check:', {
hasNavigator: typeof navigator !== 'undefined',
hasMediaDevices: !!navigator?.mediaDevices,
hasGetUserMedia: !!navigator?.mediaDevices?.getUserMedia,
isTauri: platform.metadata.isTauri,
});
const errorMsg = platform.metadata.isTauri
? 'Microphone access is not available. Please ensure:\n1. The app has microphone permissions in System Settings (macOS: System Settings > Privacy & Security > Microphone)\n2. You restart the app after granting permissions\n3. You are using Tauri v2 with a webview that supports getUserMedia'
: 'Microphone access is not available. Please ensure you are using a secure context (HTTPS or localhost) and that your browser has microphone permissions enabled.';
setError(errorMsg);
throw new Error(errorMsg);
}
}
// Request microphone access
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
});
streamRef.current = stream;
// Create MediaRecorder with preferred MIME type
const options: MediaRecorderOptions = {
mimeType: 'audio/webm;codecs=opus',
};View on GitHub (pinned to 51f49dea19)
Solutions
- Open System Settings > Privacy & Security > Microphone and enable the app, then fully quit and restart it.
- Verify `tauri.conf.json` / capabilities grant microphone access for Tauri v2 and that the app declares the usage description.
- Confirm the build is Tauri v2 with a modern WKWebView (macOS)/WebView2 (Windows).
- If denied permanently, reset the permission (`tccutil reset Microphone <bundle-id>` on macOS) and re-prompt.
Example fix
// before — synchronous check fails immediately
await startRecording();
// after — surface a re-prompt + retry after the user opens Settings
try { await startRecording(); }
catch (e) {
if (/microphone/i.test(e.message)) {
showSettingsOpenDialog(); // guide user to System Settings, then retry
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Detect the missing API early and guide the user to grant permission
if (platform.metadata.isTauri && !navigator.mediaDevices?.getUserMedia) {
throw new Error('Microphone permission needed — grant it in System Settings and restart.');
} Type guard
function hasGetUserMedia(): boolean {
return typeof navigator !== 'undefined'
&& !!navigator.mediaDevices
&& typeof navigator.mediaDevices.getUserMedia === 'function';
} Try / catch
try {
await startRecording();
} catch (e) {
if (/microphone/i.test((e as Error).message)) {
showOpenSystemSettingsDialog(); // then offer a Retry button
} else throw e;
} Prevention
- Declare microphone permission + usage description in the Tauri v2 capabilities config.
- On first run, trigger the OS permission prompt explicitly before recording.
- After the user grants permission, require an app restart and communicate that.
When it happens
Trigger: Running inside Tauri v2 but the OS has not granted microphone permission to the app; the Tauri config (capabilities/permissions) does not allow media access; the bundled webview is older than WebView2/WKWebView and lacks `getUserMedia`; permission was granted but the app was not restarted so the webview has not picked it up.
Common situations: First run on macOS where the mic permission prompt was dismissed/denied; `tauri.conf.json` capabilities missing the media/microphone permission; using a Tauri v1 build where `isTauri` is set but getUserMedia is unsupported; permission toggled in System Settings but the app must be restarted for the webview to see it.
Related errors
- Microphone access is not available. Please ensure you are us
- Navigator API is not available. This might be a Tauri config
- HTTP error! status: ${response.status}
- HTTP ${res.status}
- Failed to resolve save path from dialog
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/ac3b5bbe89cb3a78.
Report an issue: GitHub.