Zackriya-Solutions/meetily · error
Cannot access microphone: {}
Error message
Cannot access microphone: {} What it means
After obtaining a config, verify_microphone_access builds a test input stream with device.build_input_stream(). If cpal cannot create the stream (device busy, backend error, stream config rejected), the error is wrapped as 'Cannot access microphone: {}'. This means a stream could not even be constructed for the device.
Source
Thrown at frontend/src-tauri/src/audio/devices/discovery.rs:141
};
let config = device
.default_input_config()
.map_err(|e| anyhow::anyhow!("Failed to get microphone config: {}", e))?;
let callback_fired = Arc::new(AtomicBool::new(false));
let callback_fired_clone = callback_fired.clone();
let stream = device
.build_input_stream(
&config.into(),
move |_data: &[f32], _: &cpal::InputCallbackInfo| {
callback_fired_clone.store(true, Ordering::SeqCst);
},
|err| warn!("[verify_microphone_access] test stream error: {}", err),
None,
)
.map_err(|e| anyhow::anyhow!("Cannot access microphone: {}", e))?;
stream
.play()
.map_err(|e| anyhow::anyhow!("Cannot start microphone: {}", e))?;
// Wait up to 5s for the first callback.
for _ in 0..50 {
if callback_fired.load(Ordering::SeqCst) {
drop(stream);
info!("[verify_microphone_access] microphone access verified");
return Ok(());
}
std::thread::sleep(std::time::Duration::from_millis(100));
}
drop(stream);
Err(anyhow::anyhow!(
"Microphone permission not granted. Please allow microphone access in \View on GitHub (pinned to a2cb62e827)
Solutions
- Close other apps using the microphone, then retry the verification.
- Pick a different microphone device via device selection UI and retry.
- Restart the audio subsystem (or reboot) to clear stuck exclusive locks.
- Use a stream config explicitly supported by the device instead of blindly using default_input_config values.
Defensive patterns
Strategy: retry
Try / catch
match verify_microphone_access().await {
Ok(()) => start_recording(),
Err(e) if e.to_string().contains("Cannot access microphone") => {
toast.error('Microphone is busy or inaccessible. Close other apps using it and retry.');
}
Err(e) => show_error(e),
} Prevention
- Ask users to close other capture apps (Zoom/Teams/Discord) before first recording.
- Offer explicit device selection rather than relying on the default input.
- Avoid WASAPI exclusive-mode devices; prefer shared mode.
- Add a short retry with backoff around verification.
When it happens
Trigger: device.build_input_stream(config, callback, err_callback, None) returning Err - device exclusively locked by another app, invalid StreamConfig, or backend-level failure while opening the device.
Common situations: Another app holds the mic in exclusive mode (Windows WASAPI exclusive); Zoom/Teams/Discord occupying the device with broken drivers; sample rate from default_input_config rejected by driver; macOS core audio device reset.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Failed to get microphone config: {}
- Cannot start microphone: {}
- Failed to get default input config: {}
- Failed to get output config: {}
- Device not found: {}
AI-assisted analysis of Zackriya-Solutions/meetily@a2cb62e827 (2026-09-12).
Data as JSON: /api/errors/5e7c59d15c8d9782.
Report an issue: GitHub.