Zackriya-Solutions/meetily · critical · anyhow::Error

No audio streams could be created

Error message

No audio streams could be created

What it means

start_streams finished with neither microphone_stream nor system_stream set: every stream it tried to create failed or none was requested. This is the final guard before Ok(()), so recording cannot proceed at all.

Source

Thrown at frontend/src-tauri/src/audio/stream.rs:423

            info!("🔊 Creating system audio stream: {} (backend: {:?})", sys_device.name, backend);
            match AudioStream::create(sys_device.clone(), self.state.clone(), DeviceType::System, recording_sender.clone()).await {
                Ok(stream) => {
                    self.state.set_system_device(sys_device);
                    self.system_stream = Some(stream);
                    info!("✅ System audio stream created with {:?} backend", backend);
                }
                Err(e) => {
                    warn!("⚠️ Failed to create system audio stream: {}", e);
                    // Don't fail if only system audio fails
                }
            }
        } else {
            info!("ℹ️ No system device specified, skipping system audio stream");
        }

        // Ensure at least one stream was created
        if self.microphone_stream.is_none() && self.system_stream.is_none() {
            return Err(anyhow::anyhow!("No audio streams could be created"));
        }

        Ok(())
    }

    /// Stop all audio streams
    pub fn stop_streams(&mut self) -> Result<()> {
        info!("Stopping all audio streams");

        let mut errors = Vec::new();

        // Stop microphone stream
        if let Some(mic_stream) = self.microphone_stream.take() {
            if let Err(e) = mic_stream.stop() {
                error!("Failed to stop microphone stream: {}", e);
                errors.push(e);
            }
        }

View on GitHub (pinned to 0281737d87)

Solutions

  1. Verify at least one valid device name is passed and matches an enumerated device exactly
  2. Re-enumerate devices at record time instead of using cached names
  3. On macOS grant mic/screen-recording permission first (underlying stream creation fails into this guard)
  4. Surface the per-stream warnings (mic error, system warn) to the UI so the user sees which device failed
Defensive patterns

Strategy: validation

Validate before calling

// Before start_streams: confirm at least one requested device exists
fn validate_devices(mic: &Option<String>, sys: &Option<String>, known: &[String]) -> Result<(), String> {
    if mic.is_none() && sys.is_none() {
        return Err("Select at least one audio device".into());
    }
    for name in mic.iter().chain(sys.iter()) {
        if !known.iter().any(|k| k == name) {
            return Err(format!("Device not found: {name}"));
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: start_recording invoked with device names that match no enumerated device (names change with OS locale/renaming), both mic and system stream creation erroring (permissions, unplugged hardware), or both mic_device_name and system_device_name being None/skipped.

Common situations: UI passes a stale device name cached from a previous session; devices unplugged between selection and record start; macOS permissions denied so both stream opens fail into this guard; default device changed and the stored name no longer matches.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/e9562f64d7251cc1. Report an issue: GitHub.