tracel-ai/burn · error

Failed to get cache directory for Gram Matrix Loss

Error message

Failed to get cache directory for Gram Matrix Loss

What it means

`get_cache_dir` in crates/burn-vision/src/loss/gram_matrix/weights.rs:19 panics when `dirs::cache_dir()` returns None, which is how the library resolves `~/.cache/burn-pretrained-models/loss/vgg19/`. The `dirs` crate cannot determine the user cache directory, typically because the environment (HOME / XDG_CACHE_HOME on Linux) is unset or invalid. Any call chain starting at `load_vgg19_weights` will hit this before any download happens.

Source

Thrown at crates/burn-vision/src/loss/gram_matrix/weights.rs:19

use burn_core as burn;

use super::vgg19::Vgg19;
use burn::tensor::Device;
use burn_core::network::downloader::download_file_as_bytes;
use burn_store::{ModuleSnapshot, PytorchStore};
use std::fs::{File, create_dir_all, rename};
use std::io::Write;
use std::path::PathBuf;

const VGG19_URL: &str = "https://download.pytorch.org/models/vgg19-dcbb9e9d.pth";

/// Resolves and returns the local cache directory for the VGG19 weights.
///
/// Creates the directory `~/.cache/burn-pretrained-models/loss/vgg19/`
/// (or OS equivalent) if it does not already exist.
fn get_cache_dir() -> PathBuf {
    let cache_dir = dirs::cache_dir()
        .expect("Failed to get cache directory for Gram Matrix Loss")
        .join("burn-pretrained-models")
        .join("loss")
        .join("vgg19");

    if !cache_dir.exists() {
        create_dir_all(&cache_dir).expect("Failed to create cache directory for Gram Matrix Loss");
    }

    cache_dir
}

/// Downloads the pretrained weights to the `cache_path` if they don't exist already.
///
/// Requires an active internet connection on the first run. Subsequent runs will
/// use the locally cached `.pth` file.
fn download_weights_if_not_saved(cache_path: &PathBuf) {
    if !cache_path.exists() {
        let bytes = download_file_as_bytes(

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Set HOME to an existing writable user directory (e.g. `export HOME=/root` or `/home/<user>`) before running the program
  2. On Linux, set `XDG_CACHE_HOME` explicitly (e.g. `XDG_CACHE_HOME=/tmp/.cache`) as a fallback the dirs crate honors
  3. For services, configure the unit/job file to include a valid Environment=HOME=... or use EnvironmentFile
  4. Patch the call site to fall back to std::env::temp_dir() instead of panicking when dirs::cache_dir() is None

Example fix

// before: panics with 'Failed to get cache directory for Gram Matrix Loss'
let cache_dir = dirs::cache_dir()
    .expect("Failed to get cache directory for Gram Matrix Loss")
    .join("burn-pretrained-models");
// after: fall back to a temp dir
let cache_dir = dirs::cache_dir()
    .or_else(|| std::env::var_os("XDG_CACHE_HOME").map(PathBuf::from))
    .unwrap_or_else(std::env::temp_dir)
    .join("burn-pretrained-models");
Defensive patterns

Strategy: validation

Validate before calling

// Verify the cache-dir environment before calling load_vgg19_weights
fn assert_cache_dir_env() {
    match std::env::var("HOME") {
        Ok(h) if !h.is_empty() && std::path::Path::new(&h).is_dir() => {}
        _ => panic!("HOME is unset/invalid; set HOME or XDG_CACHE_HOME so dirs::cache_dir() works"),
    }
}
// or on Linux specifically:
// std::env::var_os("XDG_CACHE_HOME").or_else(|| std::env::var_os("HOME"))

Type guard

fn has_resolvable_cache_dir() -> bool {
    std::env::var_os("XDG_CACHE_HOME")
        .filter(|p| !p.is_empty())
        .or_else(|| std::env::var_os("HOME").filter(|p| !p.is_empty()))
        .map(|p| std::path::PathBuf::from(p).is_dir())
        .unwrap_or(false)
}

Try / catch

let result = std::panic::catch_unwind(|| {
    burn_vision::loss::gram_matrix::load_vgg19_weights(device)
});
if result.is_err() {
    eprintln!("cache dir unresolved — set HOME/XDG_CACHE_HOME and retry");
}

Prevention

When it happens

Trigger: Calling `load_vgg19_weights` for the Gram Matrix Loss in a process where `dirs::cache_dir()` yields None — on Linux, no HOME or XDG_CACHE_HOME in the environment; on Windows, a missing/invalid FOLDERID_LocalAppData; or a service running with a cleared environment.

Common situations: Systemd services or cron jobs without HOME set; Docker containers run with `--env-` cleared or as a non-root user with no passwd entry; CI runners executing as a bare service account; macOS launchd jobs lacking user context.

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 tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/1c710c6dc9d5b6ca. Report an issue: GitHub.