Zackriya-Solutions/meetily · warning
Device name cannot be empty
Error message
Device name cannot be empty
What it means
Thrown by AudioDevice::from_name (configuration.rs:68) when the supplied name is empty or only whitespace after trim(). The constructor parses a display string like 'MacBook Pro Microphone (input)' into an AudioDevice, and an empty name cannot carry the required (input)/(output) suffix or identify a device. This is a pure input-validation error, not a system error.
Source
Thrown at frontend/src-tauri/src/audio/devices/configuration.rs:68
pub enum DeviceType {
Input,
Output,
}
#[derive(Clone, Eq, PartialEq, Hash, Serialize, Debug)]
pub struct AudioDevice {
pub name: String,
pub device_type: DeviceType,
}
impl AudioDevice {
pub fn new(name: String, device_type: DeviceType) -> Self {
AudioDevice { name, device_type }
}
pub fn from_name(name: &str) -> Result<Self> {
if name.trim().is_empty() {
return Err(anyhow!("Device name cannot be empty"));
}
let (name, device_type) = if name.to_lowercase().ends_with("(input)") {
(
name.trim_end_matches("(input)").trim().to_string(),
DeviceType::Input,
)
} else if name.to_lowercase().ends_with("(output)") {
(
name.trim_end_matches("(output)").trim().to_string(),
DeviceType::Output,
)
} else {
return Err(anyhow!(
"Device type (input/output) not specified in the name"
));
};
View on GitHub (pinned to 0281737d87)
Solutions
- Fix the caller to pass null/None instead of an empty string when no device is selected, so the optional mic_device_name/system_device_name flow skips device resolution.
- Pre-trim and validate the value at the UI boundary before invoking the Tauri command.
- If constructing a device programmatically with a known type, bypass the parser: AudioDevice::new(name, DeviceType::Input) does not run this validation.
- Check the persisted settings JSON for an empty deviceName field and reset it to the default device.
Example fix
// before (frontend): empty string sneaks into the invoke
await invoke('start_recording', { mic_device_name: micName ?? '' });
// after: pass null so Rust receives Option::None
await invoke('start_recording', { mic_device_name: micName || null }); Defensive patterns
Strategy: validation
Validate before calling
// Rust: normalize optional device names at the IPC boundary
fn normalize_device_arg(name: &Option<String>) -> Result<Option<String>> {
match name {
Some(n) if n.trim().is_empty() => Ok(None), // treat blank as absent
Some(n) => Ok(Some(n.trim().to_string())),
None => Ok(None),
}
} Type guard
fn is_valid_device_name(name: &str) -> bool { !name.trim().is_empty() } Try / catch
// Callers of AudioDevice::from_name: map this to a select-a-device prompt
match AudioDevice::from_name(&raw) {
Err(e) if e.to_string().contains("cannot be empty") => prompt_device_selection(),
other => other,
} Prevention
- Send null (Option::None) from the frontend instead of empty strings for unset devices.
- Never persist empty-string defaults for device names; use absence.
- Trim user-supplied names at the UI boundary before invoke.
When it happens
Trigger: Calling AudioDevice::from_name("") or from_name(" "); passing a device name from persisted settings/UI state that was never initialized; forwarding a Tauri command argument mic_device_name=Some("") from the frontend (an empty select value serialized as empty string instead of null).
Common situations: Frontend sends an empty string because the settings store defaulted to '' instead of undefined; a stored device name from an older app version is blank after migration; test fixtures calling from_name with a placeholder empty value.
Related errors
- Device type (input/output) not specified in the name
- File does not exist: {}
- Parakeet transcription failed: {}
- No transcript text available. Please add some text first.
- No audio samples decoded from file
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/56d2c23a4657f0a9.
Report an issue: GitHub.