Kuberwastaken/claurst · error

No microphone found. Connect a microphone and check your…

Error message

No microphone found. Connect a microphone and check your audio settings.

What it means

Voice capture start failed because no microphone/input device is available from the default cpal audio host — device enumeration found no input device, or the default input device could not be opened. Environment-level: the machine has no mic or it is disabled/exclusively held.

Solutions

  1. Connect or enable a microphone and check OS audio settings
  2. Close other applications holding the input device exclusively
  3. Verify the default input device is set in OS settings
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at src-rust/crates/tui/src/voice_capture.rs:84 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/cde357c8dacbdf8e. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/tui/src/voice_capture.rs:84

    /// On success a `RecordingStarted` notification is sent over `event_tx`.
    /// Returns an error when no microphone is available or the `voice` feature
    /// is not compiled in.
    pub fn start_recording(
        &mut self,
        event_tx: tokio::sync::mpsc::Sender<VoiceEvent>,
    ) -> anyhow::Result<()> {
        if self.capture.is_some() {
            // Already recording — no-op.
            return Ok(());
        }

        #[cfg(feature = "voice")]
        {
            use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};

            let host = cpal::default_host();
            let device = host.default_input_device().ok_or_else(|| {
                anyhow::anyhow!(
                    "No microphone found. Connect a microphone and check your audio settings."
                )
            })?;

            let supported_cfg = device.default_input_config()?;
            let sample_rate = supported_cfg.sample_rate().0;
            let channels = supported_cfg.channels() as usize;

            let samples: Arc<Mutex<Vec<f32>>> = Arc::new(Mutex::new(Vec::new()));
            let samples_cb = samples.clone();

            let stream_cfg: cpal::StreamConfig = supported_cfg.into();
            let stream = device.build_input_stream(
                &stream_cfg,
                move |data: &[f32], _: &cpal::InputCallbackInfo| {
                    let mut buf = samples_cb.lock().unwrap();
                    if channels == 1 {
                        buf.extend_from_slice(data);

View on GitHub (pinned to b0637c97ec)