Universal-Debloater-Alliance/universal-android-debloater-next-generation · error
Unable to write file
Error message
Unable to write file
What it means
After successfully downloading the remote debloat list text, load_debloat_lists persists it to the cached lists file with `fs::write(...).expect("Unable to write file")`. If the filesystem write fails for any reason, this panics, aborting the whole load operation even though the download itself succeeded.
Solutions
- Replace .expect with error propagation: log a warning and continue using the in-memory `text`/`list` even if caching failed.
- Ensure the cache directory exists with correct permissions before writing (setup_uad_dir / create_dir_all) and check writability.
- Fall back to the previous cached file if the write fails, keeping the app functional.
- Free disk space or fix permissions on the UAD cache directory.
Example fix
// before
fs::write(cached_uad_lists.clone(), &text).expect("Unable to write file");
// after
if let Err(e) = fs::write(&cached_uad_lists, &text) {
warn!("Could not cache debloat list: {e}");
} Defensive patterns
Strategy: try-catch
Validate before calling
if !cached_uad_lists.parent().map_or(false, |p| p.exists()) {
std::fs::create_dir_all(cached_uad_lists.parent().unwrap())?;
}
let writable = std::fs::OpenOptions::new().append(true).open(&cached_uad_lists).is_ok();
if !writable { eprintln!("cache file not writable: {:?}", cached_uad_lists); } Try / catch
if let Err(e) = fs::write(&cached_uad_lists, &text) {
warn!("caching failed, continuing with in-memory list: {e}");
} Prevention
- Verify the cache directory exists and is writable before writing.
- Never make cache persistence fatal — the data is already in memory.
- Watch for read-only/sandboxed install environments (flatpak, snap, CI).
When it happens
Trigger: Calling load_debloat_lists (via update_lists, list_packages, init_apps_view, etc.) when the cache directory is missing, read-only, or full, or the cached UAD lists file is locked by another process / lacks write permission.
Common situations: Read-only config/home directories (flatpak/sandboxed installs, restricted CI users); disk full; CACHE_DIR pointing at a non-writable path after a migration; antivirus or backup tooling holding the file open on Windows.
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
- {e}
- Could not write config file to disk!
- Can't detect cache dir
- setup logging
- There must be 1 tab after serial
AI-assisted analysis of Universal-Debloater-Alliance/universal-android-debloater-next-generation@64465c850c (2026-09-12).
Data as JSON: /api/errors/fc3818c0cf7c30e0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/uad-core/src/uad_lists.rs:231
"https://raw.githubusercontent.com\
/Universal-Debloater-Alliance\
/universal-android-debloater\
/main\
/resources\
/assets\
/{LIST_FNAME}"
))
.call()
{
Ok(mut data) => {
// https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/discussions/608
let text = data
.body_mut()
.with_config()
.limit(1 << (3 + 10 + 10))
.read_to_string()
.expect("remote list is bigger than 8MiB");
fs::write(cached_uad_lists.clone(), &text).expect("Unable to write file");
let list: PackageHashMap =
serde_json::from_str(&text).expect("Unable to parse");
OperationResult::Ok(list)
}
Err(e) => {
warn!("Could not load remote debloat list: {e}");
error = true;
OperationResult::Retry(PackageHashMap::new())
}
}
})
.unwrap_or_else(|_| get_local_lists())
} else {
warn!("Could not load remote debloat list");
get_local_lists()
};
(if error { Err } else { Ok })(list)View on GitHub (pinned to 64465c850c)