{"record":{"id":"9e8e0db2a2c86040","repo":"tracel-ai/burn","slug":"could-not-get-cache-directory","errorCode":null,"errorMessage":"Could not get cache directory","messagePattern":"Could not get cache directory","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-train/src/metric/vision/afine/weights.rs","lineNumber":50,"sourceCode":"use burn_store::{ModuleSnapshot, PytorchStore};\nuse std::fs::{File, create_dir_all};\nuse std::io::Write;\nuse std::path::Path;\nuse std::path::PathBuf;\n\nuse super::calibrators::{AfineAdapter, FrCalibratorWithLimit, NrCalibrator};\nuse super::metric::Afine;\n\n/// Source URL for `afine.pth` on Hugging Face.\nconst AFINE_URL: &str =\n    \"https://huggingface.co/chaofengc/IQA-PyTorch-Weights/resolve/main/afine.pth\";\n\n/// Cached filename inside `~/.cache/burn-dataset/afine/`.\nconst CACHE_FILENAME: &str = \"afine.pth\";\n\nfn get_cache_dir() -> PathBuf {\n    let cache_dir = dirs::cache_dir()\n        .expect(\"Could not get cache directory\")\n        .join(\"burn-dataset\")\n        .join(\"afine\");\n    if !cache_dir.exists() {\n        create_dir_all(&cache_dir).expect(\"Failed to create cache directory\");\n    }\n    cache_dir\n}\n\nfn download_if_needed(url: &str, cache_path: &PathBuf, message: &str) {\n    if !cache_path.exists() {\n        let bytes = download_file_as_bytes(url, message);\n        let mut file = File::create(cache_path).expect(\"Failed to create cache file\");\n        file.write_all(&bytes).expect(\"Failed to write weights\");\n    }\n}\n\n/// Download `afine.pth` (if not cached) and load all six shards into\n/// the matching submodules of an `Afine` previously produced by","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-train/src/metric/vision/afine/weights.rs#L32-L68","documentation":"This panic comes from an `expect` on `dirs::cache_dir()` inside `get_cache_dir()` in burn-train's afine weights module. `dirs::cache_dir()` returns `None` when the OS has no user cache directory (e.g. `$XDG_CACHE_HOME`/`$HOME` unset on Linux, or no known cache path on the platform). The function is called by `load_pretrained_weights` before downloading/caching `afine.pth`, so any pretrained-weights load on such a system panics.","triggerScenarios":"Calling `load_pretrained_weights` for the afine metric on a system where `dirs::cache_dir()` returns None — typically running on Linux with `$HOME` (and `$XDG_CACHE_HOME`) unset, e.g. inside a minimal Docker container, a systemd service with a scrubbed environment, or an init system without a user session.","commonSituations":"Docker/Kubernetes containers running as root with no HOME set; CI runners with minimal env; cron jobs or daemons whose environment lacks HOME/XDG_CACHE_HOME; unusual platforms where dirs has no cache-dir rule.","solutions":["Set the XDG_CACHE_HOME (or HOME) environment variable to a writable directory before running the program, e.g. `XDG_CACHE_HOME=/tmp/.cache ./app`","If running in Docker, add `ENV XDG_CACHE_HOME=/cache` and create/mount that directory","Pre-download `afine.pth` and populate the cache dir manually if the environment cannot be fixed","Patch/fork to fall back to `std::env::temp_dir()` when `dirs::cache_dir()` is None"],"exampleFix":"// before (Dockerfile)\nCMD [\"./trainer\"]\n// after (Dockerfile)\nENV XDG_CACHE_HOME=/tmp/.cache\nRUN mkdir -p /tmp/.cache\nCMD [\"./trainer\"]","handlingStrategy":"fallback","validationCode":"// Rust: verify a usable cache dir before loading pretrained weights\nfn ensure_cache_dir() -> std::path::PathBuf {\n    let dir = dirs::cache_dir()\n        .or_else(|| std::env::var(\"XDG_CACHE_HOME\").ok().map(std::path::PathBuf::from))\n        .unwrap_or_else(std::env::temp_dir)\n        .join(\"burn-dataset\").join(\"afine\");\n    std::fs::create_dir_all(&dir).expect(\"cannot create cache dir\");\n    dir\n}\nif dirs::cache_dir().is_none() { eprintln!(\"warning: no OS cache dir; set XDG_CACHE_HOME\"); }","typeGuard":"fn cache_dir_available() -> bool { dirs::cache_dir().is_some() }","tryCatchPattern":"// expect() panics; catch at the process boundary or avoid it\nlet weights = std::panic::catch_unwind(load_pretrained_weights)\n    .map_err(|_| anyhow!(\"pretrained weight load failed; check XDG_CACHE_HOME/HOME\"))?;","preventionTips":["Always set XDG_CACHE_HOME (or HOME) in Dockerfiles, systemd units, and CI configs","Run containers with a declared, writable cache volume mounted at the cache path","Smoke-test pretrained-weight loading in the deployment environment before long training runs","Pin a single runtime user so cache ownership never changes between runs"],"tags":["panic","filesystem","cache-dir","environment"],"backgroundTag":"cache-dir-unavailable","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}