{"record":{"id":"e7077cb2bb240b08","repo":"Morganamilo/paru","slug":"failed-to-find-cache-directory","errorCode":null,"errorMessage":"failed to find cache directory","messagePattern":"failed to find cache directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/config.rs","lineNumber":581,"sourceCode":"                    {\n                        bail!(tr!(\"section can not be called {}\", section));\n                    }\n                    self.pkgbuild_repos.add_repo(section.to_string());\n                }\n                Ok(())\n            }\n            CallbackKind::Directive(_, key, value) => self.parse_directive(key, value),\n        };\n\n        let filename = cb.filename.unwrap_or(\"paru.conf\");\n        err.map_err(|e| anyhow!(\"{}:{}: {}\", filename, cb.line_number, e))\n    }\n}\n\nimpl Config {\n    pub fn new() -> Result<Self> {\n        let cache =\n            dirs::cache_dir().ok_or_else(|| anyhow!(tr!(\"failed to find cache directory\")))?;\n        let cache = cache.join(\"paru\");\n        let config =\n            dirs::config_dir().ok_or_else(|| anyhow!(tr!(\"failed to find config directory\")))?;\n        let config = config.join(\"paru\");\n        let state = dirs::state_dir()\n            .or_else(dirs::cache_dir)\n            .ok_or_else(|| anyhow!(tr!(\"failed to find state directory\")))?;\n        let state = state.join(\"paru\");\n\n        let build_dir = cache.join(\"clone\");\n        let old_old_devel_path = cache.join(\"devel.json\");\n        let old_devel_path = state.join(\"devel.json\");\n        let devel_path = state.join(\"devel.toml\");\n        let config_path = config.join(\"paru.conf\");\n\n        let old = if old_devel_path.exists() {\n            Some(&old_devel_path)\n        } else if old_old_devel_path.exists() {","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/Morganamilo/paru/blob/9ac3578807a87858651e81a02586ceb947686e7c/src/config.rs#L563-L599","documentation":"Config::new() calls dirs::cache_dir(); when the XDG cache directory cannot be determined (e.g. XDG_CACHE_HOME unset and no home directory), paru cannot locate its cache directory and bails with 'failed to find cache directory'. This happens at startup before any operation runs, so paru aborts immediately.","triggerScenarios":"dirs::cache_dir() returns None when running Config::new() at src/config.rs:581 — e.g. $HOME is unset or invalid, or XDG_CACHE_HOME points at a relative/nonexistent path that the dirs crate rejects.","commonSituations":"Running paru in a systemd unit / cron job / container with no HOME set; running as a user with a missing home directory; stripped-down Docker images lacking XDG env vars.","solutions":["Set HOME to the user's real home directory before running paru","Set XDG_CACHE_HOME (e.g. export XDG_CACHE_HOME=/home/user/.cache) and ensure it exists","If running under systemd, add Environment=HOME=%h or use the user's session environment","Run paru as the intended user, not as a system account without a home dir"],"exampleFix":"# before (systemd unit)\n[Service]\nExecStart=/usr/bin/paru -Syu\n\n// after (systemd unit)\n[Service]\nEnvironment=HOME=%h\nExecStart=/usr/bin/paru -Syu","handlingStrategy":"validation","validationCode":"// before invoking paru programmatically\nif std::env::var_os(\"HOME\").is_none() && std::env::var_os(\"XDG_CACHE_HOME\").is_none() {\n    eprintln!(\"HOME or XDG_CACHE_HOME must be set\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always run paru inside a user session with HOME set","In scripts/services, explicitly export HOME and XDG_CACHE_HOME","In containers, create the user with a real home directory"],"tags":["environment","xdg","cache-dir","startup"],"backgroundTag":"missing-env-var","analyzedSha":"9ac3578807a87858651e81a02586ceb947686e7c","analyzedAt":"2026-09-12T04:57:59.861Z","contentChangedAt":"2026-09-12T04:57:59.861Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}