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

  1. Close other apps using the microphone, then retry the verification.
  2. Pick a different microphone device via device selection UI and retry.
  3. Restart the audio subsystem (or reboot) to clear stuck exclusive locks.
  4. 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

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


AI-assisted analysis of Zackriya-Solutions/meetily@a2cb62e827 (2026-09-12). Data as JSON: /api/errors/5e7c59d15c8d9782. Report an issue: GitHub.