{"record":{"id":"f6917d488ce3cccc","repo":"tracel-ai/burn","slug":"failed-to-create-vgg19-cache-file-for-gram-matrix","errorCode":null,"errorMessage":"Failed to create VGG19 cache file for Gram Matrix Loss","messagePattern":"Failed to create VGG19 cache file for Gram Matrix Loss","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-vision/src/loss/gram_matrix/weights.rs","lineNumber":47,"sourceCode":"}\n\n/// Downloads the pretrained weights to the `cache_path` if they don't exist already.\n///\n/// Requires an active internet connection on the first run. Subsequent runs will\n/// use the locally cached `.pth` file.\nfn download_weights_if_not_saved(cache_path: &PathBuf) {\n    if !cache_path.exists() {\n        let bytes = download_file_as_bytes(\n            VGG19_URL,\n            \"Downloading VGG19 ImageNet weights for Gram Matrix Loss...\",\n        );\n\n        // Write to a temporary file. If writing gets completed, then rename to the actual/correct name.\n        // If writing is not completed, the file with the correct name (i.e. `cache_path`) will not exist\n        // so this code block can run again which is the desired behavior.\n        let temp_path = cache_path.with_extension(\"pth.tmp\");\n        let mut file = File::create(&temp_path)\n            .expect(\"Failed to create VGG19 cache file for Gram Matrix Loss\");\n        file.write_all(&bytes)\n            .expect(\"Failed to write VGG19 weights to the cache file for Gram Matrix Loss\");\n\n        rename(temp_path, cache_path)\n            .expect(\"Failed to rename temporary file to the actual VGG19 cache file name for Gram Matrix Loss\");\n    }\n}\n\n/// Loads ImageNet pretrained weights into the provided VGG19 feature extractor.\n///\n/// This function downloads the official PyTorch VGG19 weights, remaps the keys\n/// from PyTorch's `features.X` format to Burn's `convX_Y` format, and loads\n/// them into the module.\n///\n/// # Arguments\n///\n/// - `vgg19` - An initialized VGG19 module with random weights.\n///","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-vision/src/loss/gram_matrix/weights.rs#L29-L65","documentation":"`download_weights_if_not_saved` in crates/burn-vision/src/loss/gram_matrix/weights.rs:47 panics when `File::create` fails on the temporary file `cache_path.with_extension(\"pth.tmp\")` used for an atomic VGG19 weights download. The library deliberately writes to a temp name first and renames it only after a complete write, so a panic here means the temp file could not even be created. The final cache file is untouched, so a retry is safe.","triggerScenarios":"Calling `load_vgg19_weights` with a missing cache file, where creating `<cache>.pth.tmp` fails: the cache directory does not exist or is not writable (e.g. it was removed between `get_cache_dir` and this point), a leftover `.pth.tmp` exists with no write permission, or the path component is a directory/file conflict.","commonSituations":"Two processes racing where one deleted or re-created the cache directory; a stale read-only `.pth.tmp` from a previous crashed run run under a different user; disk full so create fails with ENOSPC; temp name colliding with a directory named `weights.pth.tmp`.","solutions":["Delete stale temp files in the cache dir: `rm ~/.cache/burn-pretrained-models/loss/vgg19/*.pth.tmp` and retry","Verify the vgg19 cache directory exists and is writable by the current user (`ls -ld`, `touch` test) and fix permissions","Free disk space if `df` shows the cache filesystem is full","Rerun single-threaded or per-user cache dirs to avoid concurrent downloaders clobbering each other"],"exampleFix":"// before: panic on temp-file creation\nlet temp_path = cache_path.with_extension(\"pth.tmp\");\nlet mut file = File::create(&temp_path)\n    .expect(\"Failed to create VGG19 cache file for Gram Matrix Loss\");\n// after: include the path in the error for diagnosis\nlet temp_path = cache_path.with_extension(\"pth.tmp\");\nlet mut file = File::create(&temp_path).with_context(|| {\n    format!(\"Failed to create temp file {} for VGG19 weights\", temp_path.display())\n})?;","handlingStrategy":"retry","validationCode":"// Clean stale temp files and verify the dir is writable before downloading\nlet cache_dir = dirs::cache_dir().unwrap().join(\"burn-pretrained-models/loss/vgg19\");\nfor entry in std::fs::read_dir(&cache_dir).into_iter().flatten().flatten() {\n    let p = entry.path();\n    if p.extension().map_or(false, |e| e == \"tmp\") {\n        let _ = std::fs::remove_file(&p);\n    }\n}\nassert!(OpenOptions::new().write(true).create(true)\n    .open(cache_dir.join(\".probe\")).is_ok(), \"vgg19 cache dir not writable\");","typeGuard":"fn temp_files_stale(cache_dir: &std::path::Path) -> bool {\n    std::fs::read_dir(cache_dir).map(|rd| rd.flatten()\n        .any(|e| e.path().to_string_lossy().ends_with(\".pth.tmp\")))\n        .unwrap_or(false)\n}","tryCatchPattern":"for attempt in 1..=3 {\n    match std::panic::catch_unwind(||\n        burn_vision::loss::gram_matrix::load_vgg19_weights(device)\n    ) {\n        Ok(_) => break,\n        Err(_) if attempt < 3 => {\n            // remove stale .pth.tmp then back off and retry\n            std::thread::sleep(std::time::Duration::from_secs(2u64.pow(attempt)));\n        }\n        Err(_) => eprintln!(\"VGG19 cache download failed after retries\"),\n    }\n}","preventionTips":["Serialize weight downloads across processes (file lock) or use per-user cache dirs","Periodically clean *.pth.tmp leftovers from the cache dir","Ensure adequate disk space before first-run downloads","Run under a single consistent user so temp files stay writable"],"tags":["filesystem","cache","panics","concurrency","burn"],"backgroundTag":"cache-file-create-failed","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"}