Universal-Debloater-Alliance/universal-android-debloater-next-generation · error
Device should be selected
Error message
Device should be selected
What it means
In UadGui::update, toggling MultiUserMode on iterates the selected device's user list, unwrapping `self.selected_device` with `.expect("Device should be selected")`. The invariant assumed is that multi-user mode can only be toggled when a device is connected; if the toggle message arrives with no device selected (e.g. device disconnected mid-iteration or state desync), the GUI panics inside the update loop.
Solutions
- Replace .expect with a None guard: `if let Some(device) = &self.selected_device { ... }` (or `let Some(device) = ... else { return }`) so the toggle is a no-op without a device.
- Disable the MultiUserMode toggle in the UI when no device is selected.
- Clear/reset the multi-user toggle state whenever selected_device becomes None on device disconnect.
- Log a warning when the message arrives deviceless to surface the state desync.
Example fix
// before
self.selected_device
.as_ref()
.expect("Device should be selected")
.user_list
// after
let Some(device) = self.selected_device.as_ref() else { return };
device.user_list Defensive patterns
Strategy: type-guard
Validate before calling
// in the message handler, before touching the device
if self.selected_device.is_none() {
eprintln!("MultiUserMode toggled with no device selected; ignoring");
return;
} Type guard
fn device_selected(gui: &UadGui) -> bool { gui.selected_device.is_some() } Try / catch
let Some(device) = self.selected_device.as_ref() else { return }; // then use device.user_list Prevention
- Guard every selected_device unwrap in GUI update paths with an early return.
- Clear dependent toggles (multi-user mode) when the device disconnects.
- Disable device-dependent UI controls while no device is selected.
When it happens
Trigger: Sending SettingsMessage::MultiUserMode(true) while self.selected_device is None: the device was unplugged/removed after the toggle was rendered, the GUI state was reset without clearing the settings view, or multi-user mode is toggled before any device connects.
Common situations: Toggling multi-user selection in the settings view right as the ADB device disconnects; resuming the app with stale settings state and no device attached; race between device list refresh and the toggle message.
Related errors
- UAD-list type must be selected
- pack-state must be selected
- {e}
- There must be 1 tab after serial
- There must be at least 1 ':'-separated component
AI-assisted analysis of Universal-Debloater-Alliance/universal-android-debloater-next-generation@64465c850c (2026-09-12).
Data as JSON: /api/errors/e4c2c0bcc9a54dd6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/uad-gui/src/gui.rs:254
{
self.apps_view.update(
&mut self.settings_view,
&mut self.selected_device.clone().unwrap_or_default(),
&mut self.update_state.uad_list,
AppsMessage::RestoringDevice(output.clone()),
);
}
if self.nb_running_async_adb_commands == 0 {
return self.update(Message::RefreshButtonPressed);
}
}
SettingsMessage::MultiUserMode(toggled) if toggled => {
for user in self.apps_view.phone_packages.clone() {
for (i, _) in user.iter().filter(|&pkg| pkg.selected).enumerate() {
for u in self
.selected_device
.as_ref()
.expect("Device should be selected")
.user_list
.iter()
.filter(|&u| !u.protected)
{
self.apps_view.phone_packages[u.index][i].selected = true;
}
}
}
}
_ => (),
}
self.settings_view
.update(
&self.selected_device.clone().unwrap_or_default(),
&self.apps_view.phone_packages,
&mut self.nb_running_async_adb_commands,
msg,
self.apps_view.selected_user,View on GitHub (pinned to 64465c850c)