sinelaw/fresh · error
Could not determine cache directory
Error message
Could not determine cache directory
What it means
extract_plugins needs a base cache directory to atomically stage extracted embedded plugins (via rename). If get_cache_dir() returns None (no XDG_CACHE_HOME, no HOME, and no fallback the helper recognizes), it returns io::ErrorKind::NotFound 'Could not determine cache directory'.
Solutions
- Set XDG_CACHE_HOME (or HOME) to a writable directory before launching
- Launch the editor with a proper user environment (avoid env -i / sanitized service units without Environment=HOME=...)
- Make the caller handle the None case with an explicit fallback (e.g. std::env::temp_dir())
- Pre-extract plugins so the runtime extraction path is not needed
Example fix
// before
std::process::Command::new("fresh-editor").env_clear().spawn()?;
// after
std::process::Command::new("fresh-editor")
.env("XDG_CACHE_HOME", "/home/dev/.cache")
.spawn()?; Defensive patterns
Strategy: fallback
Validate before calling
fn cache_dir_resolvable() -> bool {
std::env::var_os("XDG_CACHE_HOME").filter(|v| !v.is_empty()).is_some()
|| std::env::var_os("HOME").filter(|v| !v.is_empty()).is_some()
} Try / catch
match get_embedded_plugins_dir() {
Ok(dir) => dir,
Err(e) if e.kind() == io::ErrorKind::NotFound => {
std::env::set_var("XDG_CACHE_HOME", "/tmp/fresh-cache");
get_embedded_plugins_dir()?
}
Err(e) => return Err(e.into()),
} Prevention
- Always set HOME/XDG_CACHE_HOME in systemd units, cron jobs, and containers
- Avoid launching with a fully sanitized environment (env -i)
- Provide an explicit CLI/env override for the cache directory
When it happens
Trigger: Calling get_embedded_plugins_dir()/extract_plugins() in an environment where the cache directory cannot be resolved: service accounts without HOME, sanitized environment (systemd, cron, containers), or XDG_CACHE_HOME set to an empty/invalid value.
Common situations: Running the editor under systemd or a container runtime that strips HOME/XDG vars; CI jobs with minimal env; launching via a wrapper script that clears the environment.
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
- Could not determine config directory
- Could not determine data directory
- Could not determine data directory
- editor.spawnHostProcess is not implemented (missing…
- editor.spawnProcess is not implemented (missing…
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/3ee0891ac4ec6b42.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/src/services/plugins/embedded.rs:68
/// Get the cache directory for extracted plugins
fn get_cache_dir() -> Option<PathBuf> {
dirs::cache_dir().map(|p| p.join("fresh").join("embedded-plugins"))
}
/// Extract embedded plugins to the cache directory.
///
/// Concurrency contract: this function is called via a process-local
/// `OnceLock`, but multiple test processes (e.g. cargo-nextest) may
/// each call it concurrently against the same on-disk directory. We
/// publish atomically: extract into a sibling `.pending.<pid>.<nanos>`
/// directory, write a `.extracted` marker, then `rename` into place.
/// `rename` over an existing non-empty directory fails on POSIX, so
/// only one publisher wins; losers fall back to the winner's
/// directory. Readers gate on the marker file so they never observe a
/// half-extracted tree.
fn extract_plugins() -> Result<PathBuf, std::io::Error> {
let cache_base = get_cache_dir().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
"Could not determine cache directory",
)
})?;
let content_hash = PLUGINS_CONTENT_HASH.trim();
let cache_dir = cache_base.join(content_hash);
let marker = cache_dir.join(".extracted");
if marker.exists() {
tracing::info!("Using cached embedded plugins from: {:?}", cache_dir);
return Ok(cache_dir);
}
tracing::info!("Extracting embedded plugins to: {:?}", cache_dir);
std::fs::create_dir_all(&cache_base)?;
let pid = std::process::id();View on GitHub (pinned to 67894ca546)