{"record":{"id":"56d2c23a4657f0a9","repo":"Zackriya-Solutions/meetily","slug":"device-name-cannot-be-empty","errorCode":null,"errorMessage":"Device name cannot be empty","messagePattern":"Device name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src-tauri/src/audio/devices/configuration.rs","lineNumber":68,"sourceCode":"pub enum DeviceType {\n    Input,\n    Output,\n}\n\n#[derive(Clone, Eq, PartialEq, Hash, Serialize, Debug)]\npub struct AudioDevice {\n    pub name: String,\n    pub device_type: DeviceType,\n}\n\nimpl AudioDevice {\n    pub fn new(name: String, device_type: DeviceType) -> Self {\n        AudioDevice { name, device_type }\n    }\n\n    pub fn from_name(name: &str) -> Result<Self> {\n        if name.trim().is_empty() {\n            return Err(anyhow!(\"Device name cannot be empty\"));\n        }\n\n        let (name, device_type) = if name.to_lowercase().ends_with(\"(input)\") {\n            (\n                name.trim_end_matches(\"(input)\").trim().to_string(),\n                DeviceType::Input,\n            )\n        } else if name.to_lowercase().ends_with(\"(output)\") {\n            (\n                name.trim_end_matches(\"(output)\").trim().to_string(),\n                DeviceType::Output,\n            )\n        } else {\n            return Err(anyhow!(\n                \"Device type (input/output) not specified in the name\"\n            ));\n        };\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/audio/devices/configuration.rs#L50-L86","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before (frontend): empty string sneaks into the invoke\nawait invoke('start_recording', { mic_device_name: micName ?? '' });\n\n// after: pass null so Rust receives Option::None\nawait invoke('start_recording', { mic_device_name: micName || null });","handlingStrategy":"validation","validationCode":"// Rust: normalize optional device names at the IPC boundary\nfn normalize_device_arg(name: &Option<String>) -> Result<Option<String>> {\n    match name {\n        Some(n) if n.trim().is_empty() => Ok(None), // treat blank as absent\n        Some(n) => Ok(Some(n.trim().to_string())),\n        None => Ok(None),\n    }\n}","typeGuard":"fn is_valid_device_name(name: &str) -> bool { !name.trim().is_empty() }","tryCatchPattern":"// Callers of AudioDevice::from_name: map this to a select-a-device prompt\nmatch AudioDevice::from_name(&raw) {\n    Err(e) if e.to_string().contains(\"cannot be empty\") => prompt_device_selection(),\n    other => other,\n}","preventionTips":["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."],"tags":["audio","validation","device-name","tauri-ipc"],"backgroundTag":"empty-string-validation","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}