Universal-Debloater-Alliance/universal-android-debloater-next-generation · critical

Could not write config file to disk!

Error message

Could not write config file to disk!

What it means

save_device_settings serializes the whole config to TOML and writes it to CONFIG_FILE; if fs::write fails it panics with "Could not write config file to disk!". The library treats inability to persist settings as a hard failure, raised on every settings-mutating handler.

Solutions

  1. Check write permissions on the config directory and file (ls -l, try touching the file as the same user).
  2. Free disk space / check quota.
  3. If sandboxed (flatpak, snap), grant access to the config path or set a writable XDG_CONFIG_HOME.
  4. Wrap the save call in catch_unwind or patch to return Result and surface a UI error instead of panicking.

Example fix

// before
fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
// after
if let Err(e) = fs::write(&*CONFIG_FILE, toml) {
    error!("Could not write config file: {e}");
    return; // or propagate a Result::Err to the caller
}
Defensive patterns

Strategy: validation

Validate before calling

let cfg_dir = config_file.parent().unwrap_or(std::path::Path::new("."));
if !cfg_dir.is_dir() { return Err("config dir missing"); }
let probe = cfg_dir.join(".write_test");
std::fs::write(&probe, b"").map_err(|e| format!("config dir not writable: {e}"))?;
let _ = std::fs::remove_file(&probe);

Type guard

fn config_writable(p: &std::path::Path) -> bool {
    if let Some(d) = p.parent() { d.is_dir() && std::fs::OpenOptions::new().append(true).open(p).or_else(|_| std::fs::OpenOptions::new().write(true).create_new(true).open(d.join(".probe"))).is_ok() } else { false }
}

Try / catch

std::panic::catch_unwind(|| config.save_device_settings(general, device_settings))
    .map_err(|_| "could not write config file to disk")?;

Prevention

When it happens

Trigger: Calling save_device_settings (via handle_expert_mode, handle_disable_mode, handle_multi_user_mode, handle_apply_theme, handle_folder_chosen) when CONFIG_FILE cannot be written: parent dir missing/locked, read-only filesystem, disk full, or permission denied.

Common situations: Read-only $HOME, flatpak/sandbox blocking the config path, another process holding a mandatory lock, quota exceeded, or CONFIG_DIR setup previously failed.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of Universal-Debloater-Alliance/universal-android-debloater-next-generation@64465c850c (2026-09-12). Data as JSON: /api/errors/5e49276c44f3b986. Report an issue: GitHub.

Appendix: source

Thrown at crates/uad-core/src/config.rs:75

impl Config {
    pub fn save_device_settings(
        &mut self,
        device_settings: DeviceSettings,
        general: GeneralSettings,
    ) {
        if let Some(device) = self
            .devices
            .iter_mut()
            .find(|x| x.device_id == device_settings.device_id)
        {
            *device = device_settings;
        } else {
            self.devices.push(device_settings);
        }
        self.general = general;
        let toml = toml::to_string(&self).unwrap();
        fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
    }

    #[must_use]
    pub fn load_configuration_file() -> Self {
        match fs::read_to_string(&*CONFIG_FILE) {
            Ok(s) => match toml::from_str(&s) {
                Ok(config) => return config,
                Err(e) => error!("Invalid config file: `{e}`"),
            },
            Err(e) => error!("Failed to read config file: `{e}`"),
        }
        error!("Restoring default config file");
        let toml = toml::to_string(&Self::default()).unwrap();
        fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
        Self::default()
    }
}

View on GitHub (pinned to 64465c850c)