{"record":{"id":"74ed127a48a5f2f4","repo":"Kuberwastaken/claurst","slug":"no-input-device-available","errorCode":null,"errorMessage":"No input device available","messagePattern":"No input device available","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-rust/crates/core/src/voice.rs","lineNumber":396,"sourceCode":"    }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Audio capture (cpal, feature-gated)\r\n// ---------------------------------------------------------------------------\r\n\r\n#[cfg(feature = \"voice\")]\r\nasync fn record_audio(\r\n    is_recording: Arc<AtomicBool>,\r\n    event_tx: mpsc::Sender<VoiceEvent>,\r\n) -> anyhow::Result<(Vec<f32>, u32)> {\r\n    use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};\r\n    use std::time::Duration;\r\n\r\n    let host = cpal::default_host();\r\n    let device = host\r\n        .default_input_device()\r\n        .ok_or_else(|| anyhow::anyhow!(\"No input device available\"))?;\r\n\r\n    let supported_config = device.default_input_config()?;\r\n    let sample_rate = supported_config.sample_rate().0;\r\n    let channels = supported_config.channels() as usize;\r\n\r\n    let samples: Arc<Mutex<Vec<f32>>> = Arc::new(Mutex::new(Vec::new()));\r\n    let samples_clone = samples.clone();\r\n\r\n    let err_tx = event_tx.clone();\r\n    let is_recording_for_err = is_recording.clone();\r\n    let stream = {\r\n        let config: cpal::StreamConfig = supported_config.into();\r\n        device.build_input_stream(\r\n            &config,\r\n            move |data: &[f32], _: &cpal::InputCallbackInfo| {\r\n                // Mix down to mono if needed\r\n                let mut s = samples_clone.lock().unwrap();\r\n                if channels == 1 {\r","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/core/src/voice.rs#L378-L414","documentation":"record_audio asks cpal's default host for the default input device; when none exists it returns this error before any stream setup. The library cannot capture audio without a device, so it fails immediately with a clear message.","triggerScenarios":"record_audio running on a machine where cpal::default_host().default_input_device() returns None — no microphone, no audio subsystem, or audio daemon not running.","commonSituations":"Headless servers/containers with no sound hardware; SSH sessions without PulseAudio/PipeWire; VM with no audio passthrough; microphone disabled at BIOS/OS level; PulseAudio not started.","solutions":["Connect or enable a microphone/input device.","Start the system audio server (pipewire/pulseaudio) on Linux.","Check availability() or enumerate input devices before attempting recording and show a friendly message.","On Linux, install ALSA/PipeWire dev runtime libs so cpal's host can find devices."],"exampleFix":"// before\nlet text = voice.record_and_transcribe().await?;\n// after\nif cpal::default_host().default_input_device().is_none() {\n    eprintln!(\"no microphone detected; voice input disabled\");\n    return Ok(());\n}\nlet text = voice.record_and_transcribe().await?;","handlingStrategy":"fallback","validationCode":"fn has_input_device() -> bool {\n    cpal::default_host().default_input_device().is_some()\n}","typeGuard":null,"tryCatchPattern":"match voice.record_and_transcribe().await {\n    Ok(t) => t,\n    Err(e) if e.to_string().contains(\"No input device\") => {\n        eprintln!(\"no microphone; falling back to typed input\");\n        typed_input()?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Enumerate input devices at startup; disable voice if empty.","On Linux verify PipeWire/PulseAudio is running before recording.","Provide a non-voice fallback input path."],"tags":["audio","cpal","hardware","microphone"],"backgroundTag":"resource-not-found","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}