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

Can't detect cache dir

Error message

Can't detect cache dir

What it means

A panic raised while initializing the CACHE_DIR lazy static at crate load: dirs::cache_dir() returned None, so expect() aborted before the app could start. This happens when the platform provides no user cache directory — e.g. on Linux when neither XDG_CACHE_HOME nor HOME is set (common under service managers, cron, or stripped container environments), since the dirs crate derives the cache path from those variables. Because it fires in a LazyLock on first access to CACHE_DIR, the crash occurs at startup rather than at the call site that uses the path.

Solutions

  1. Set HOME to a writable directory before launching the app.
  2. Set XDG_CACHE_HOME explicitly to a writable path.
  3. Grant the service account a home directory or pass Environment=HOME=... in the unit file.
  4. Pre-check dirs::cache_dir() in your launcher and abort with a friendly message.

Example fix

// before
let dir = dirs::cache_dir().expect("Can't detect cache dir");
// after
let dir = dirs::cache_dir().unwrap_or_else(|| {
    std::env::var("XDG_CACHE_HOME").or_else(|_| std::env::var("HOME")).map(PathBuf::from).unwrap_or_else(|_| PathBuf::from("/tmp"))
});
Defensive patterns

Strategy: validation

Validate before calling

let ok = std::env::var("XDG_CACHE_HOME").map(|v| !v.is_empty()).unwrap_or(false)
    || std::env::var("HOME").map(|v| !v.is_empty()).unwrap_or(false);
if !ok { return Err("cannot determine cache dir: set HOME or XDG_CACHE_HOME"); }

Type guard

fn cache_dir_available() -> bool { dirs::cache_dir().is_some() }

Try / catch

let dir = std::panic::catch_unwind(|| uad_core::CACHE_DIR.clone())
    .unwrap_or_else(|_| { eprintln!("no cache dir: set HOME or XDG_CACHE_HOME"); std::process::exit(1); });

Prevention

When it happens

Trigger: First read of uad_core::CACHE_DIR when dirs::cache_dir() returns None — on Linux, XDG_CACHE_HOME unset/empty AND $HOME unset/empty; analogous conditions on other platforms.

Common situations: Container or systemd service with no HOME env var, ephemeral CI runners, running as a headless system user, sanitized environment.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at crates/uad-core/src/lib.rs:23

    clippy::uninlined_format_args,
    clippy::result_unit_err,
    reason = "Doc+style pedantic lints are out-of-scope for this pass"
)]

pub mod adb;
pub mod config;
pub mod save;
pub mod sync;
pub mod uad_lists;
pub mod update;
pub mod utils;

use std::path::PathBuf;
use std::sync::LazyLock;
pub static CONFIG_DIR: LazyLock<PathBuf> =
    LazyLock::new(|| utils::setup_uad_dir(&dirs::config_dir().expect("Can't detect config dir")));
pub static CACHE_DIR: LazyLock<PathBuf> =
    LazyLock::new(|| utils::setup_uad_dir(&dirs::cache_dir().expect("Can't detect cache dir")));

View on GitHub (pinned to 64465c850c)