{"record":{"id":"db6960df7fe75b14","repo":"Universal-Debloater-Alliance/universal-android-debloater-next-generation","slug":"e","errorCode":null,"errorMessage":"{e}","messagePattern":"\\{e\\}","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/uad-core/src/utils.rs","lineNumber":139,"sourceCode":"        let package = CorePackage {\n            name: p_name.clone(),\n            description,\n            removal,\n            state,\n            list,\n        };\n        user_package.push(package);\n    }\n    user_package.sort_by_key(|package| package.name.to_lowercase());\n    user_package\n}\n\n#[must_use]\npub fn setup_uad_dir(dir: &Path) -> PathBuf {\n    let dir = dir.join(\"uad\");\n    if let Err(e) = fs::create_dir_all(&dir) {\n        error!(\"Can't create directory: {}\", dir.display());\n        panic!(\"{e}\");\n    }\n    dir\n}\n\n/// Open a directory or file with the system's default file manager.\npub fn open_url(dir: PathBuf) {\n    const OPENER: &str = match std::env::consts::OS.as_bytes() {\n        b\"windows\" => \"explorer\",\n        b\"macos\" => \"open\",\n        // \"linux\"\n        _ => \"xdg-open\",\n    };\n    match std::process::Command::new(OPENER).arg(dir).output() {\n        Ok(o) => {\n            if !o.status.success() {\n                // Use lossy conversion for stderr - some systems (like Windows)\n                // may output non-UTF8 characters in error messages\n                let stderr = String::from_utf8_lossy(&o.stderr);","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/64465c850c7ed36329e67165ac08501abffb218e/crates/uad-core/src/utils.rs#L121-L157","documentation":"setup_uad_dir creates the app's \"uad\" subdirectory under a given base path and panics if fs::create_dir_all fails. The panic message is the raw std::io::Error Display, so the text is whatever the OS reported (e.g. permission denied). It is thrown because the library treats an unusable data directory as unrecoverable at startup.","triggerScenarios":"Calling setup_uad_dir (directly or via CONFIG_DIR/CACHE_DIR LazyLocks in lib.rs) when the base path's parent does not exist and cannot be created, or exists but is not writable.","commonSituations":"Read-only $HOME or $XDG_CONFIG_HOME, running as a service user without a home directory, sandboxed/flatpak environments blocking writes, disk full, or base path resolving to a file instead of a directory.","solutions":["Ensure the base directory (e.g. dirs::config_dir()) exists and is writable by the current user before launching.","Set XDG_CONFIG_HOME / XDG_CACHE_HOME (or run with a valid HOME) to point to a writable location.","Check disk space and that the target path is not an existing regular file.","Catch the panic upstream (catch_unwind) or call setup_uad_dir early on a known-good path to fail fast with a clear message."],"exampleFix":"// before\nlet dir = base.join(\"uad\"); // panics if unwritable\n// after\nlet dir = base.join(\"uad\");\nif let Err(e) = std::fs::create_dir_all(&dir) {\n    eprintln!(\"cannot create {}: {e}\", dir.display());\n    std::process::exit(1);\n}","handlingStrategy":"validation","validationCode":"let dir = base.join(\"uad\");\nif !base.is_dir() { return Err(\"base path is not a directory\"); }\nlet probe = dir.join(\".write_test\");\nstd::fs::write(&probe, b\"\").map_err(|e| format!(\"dir not writable: {e}\"))?;\nlet _ = std::fs::remove_file(&probe);","typeGuard":"fn is_writable_dir(p: &std::path::Path) -> bool {\n    p.is_dir() && std::fs::OpenOptions::new().write(true).open(p).is_ok()\n}","tryCatchPattern":"let dir = std::panic::catch_unwind(|| setup_uad_dir(&base))\n    .unwrap_or_else(|_| { eprintln!(\"cannot create uad dir under {}\", base.display()); std::process::exit(1); });","preventionTips":["Verify HOME/XDG_CONFIG_HOME are set and writable before launching the app.","Never point the base path at an existing regular file.","Run an early write-probe at startup to fail fast with a clear message.","In sandboxes (flatpak/snap), declare filesystem permissions for the config path."],"tags":["filesystem","panic","directory-creation","rust"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"64465c850c7ed36329e67165ac08501abffb218e","analyzedAt":"2026-09-12T09:09:23.137Z","contentChangedAt":"2026-09-12T09:09:23.137Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}