Zackriya-Solutions/meetily · error

Microphone permission not granted. Please allow microphone a

Error message

Microphone permission not granted. Please allow microphone access in System Settings > Privacy & Security > Microphone, then try again.

What it means

verify_microphone_access starts the test stream and waits up to 5 seconds (50 x 100ms) for the first audio callback. If no callback fires, it concludes the OS is silently blocking microphone capture and returns this explicit permission error naming the macOS System Settings path.

Source

Thrown at frontend/src-tauri/src/audio/devices/discovery.rs:158

            )
            .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 \
             System Settings > Privacy & Security > Microphone, then try again."
        ))
    })
    .await
    .map_err(|e| anyhow::anyhow!("Microphone verification task failed: {}", e))?
}

View on GitHub (pinned to a2cb62e827)

Solutions

  1. Grant microphone access: macOS System Settings > Privacy & Security > Microphone, enable the app, then restart it.
  2. On Windows, enable Settings > Privacy & security > Microphone > 'Let desktop apps access your microphone'.
  3. Reset TCC for the app if the toggle is already on but callbacks still never fire (tccutil reset Microphone <bundle-id>).
  4. Confirm with a system app (Voice Memos) that the device physically captures audio.
Defensive patterns

Strategy: try-catch

Validate before calling

// Frontend: check permission before recording on macOS/Tauri
const status = await invoke<string>('check_microphone_permission');
if (status !== 'granted') {
  showPermissionDialog('System Settings > Privacy & Security > Microphone');
  return;
}

Try / catch

try {
  await invoke('start_recording', args);
} catch (e) {
  if (String(e).includes('permission not granted')) {
    openMacOsPermissionHelp(); // deep-link: x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone
  } else { throw e; }
}

Prevention

When it happens

Trigger: Stream built and playing, but the input callback never fires within 5s - typical on macOS when the app lacks Microphone permission under Privacy & Security, or when a device delivers no data though play() succeeded.

Common situations: First app launch where the macOS TCC permission prompt was denied or dismissed; app moved/resigned so TCC sees a different code signature; Windows privacy setting 'Allow desktop apps to access your microphone' is off; muted/disconnected hardware delivering silence-less no-callback states.

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/2d238b75cc50c8cc. Report an issue: GitHub.