GraphiteEditor/Graphite · error
Failed to get data directory
Error message
Failed to get data directory
What it means
Panic when dirs::data_dir() returns None. The dirs crate returns an Option: on Linux it is None when neither XDG_DATA_HOME nor a usable HOME is set (empty or unset); on Windows it wraps the Known Folder API which can fail in stripped-down environments; on macOS it is None when the home directory cannot be determined. The desktop app then cannot locate its data directory and aborts.
Source
Thrown at desktop/src/dirs.rs:32
tracing::error!("Failed to read directory at {path:?}");
return;
};
for entry in entries.flatten() {
let entry_path = entry.path();
if entry_path.is_dir() {
if let Err(e) = fs::remove_dir_all(&entry_path) {
tracing::error!("Failed to remove directory at {:?}: {}", entry_path, e);
}
} else if entry_path.is_file() {
if let Err(e) = fs::remove_file(&entry_path) {
tracing::error!("Failed to remove file at {:?}: {}", entry_path, e);
}
}
}
}
pub(crate) fn app_data_dir() -> PathBuf {
let path = dirs::data_dir().expect("Failed to get data directory").join(APP_DIRECTORY_NAME);
ensure_dir_exists(&path);
path
}
pub(crate) fn app_autosave_documents_dir() -> PathBuf {
let path = app_data_dir().join(APP_DOCUMENTS_DIRECTORY_NAME);
ensure_dir_exists(&path);
path
}
pub(crate) fn app_resources_dir() -> PathBuf {
let path = app_data_dir().join(APP_RESOURCES_DIRECTORY_NAME);
ensure_dir_exists(&path);
path
}
// TODO: Eventually remove this cleanup code for the old "browser" CEF directory
pub(crate) fn delete_old_cef_browser_directory() {View on GitHub (pinned to c507b35645)
Solutions
- Set a valid HOME (or XDG_DATA_HOME) in the process environment: docker -e HOME=/home/user or Environment=HOME=... in the service unit
- Verify with env | grep -E 'HOME|XDG_DATA_HOME' from the same launcher context
- Fix the launcher/shell profile that strips environment variables
- For tests, provide an explicit temp dir as the data dir instead of relying on the ambient environment
Example fix
// before
let path = dirs::data_dir().expect("Failed to get data directory").join(APP_DIRECTORY_NAME);
// after
let base = dirs::data_dir().or_else(|| std::env::var("HOME").ok().map(PathBuf::from).map(|h| h.join(".local/share")))
.unwrap_or_else(|| panic!("Failed to get data directory: set HOME or XDG_DATA_HOME"));
let path = base.join(APP_DIRECTORY_NAME); Defensive patterns
Strategy: validation
Validate before calling
// Check the environment before any dirs::data_dir() call
fn data_base_dir() -> Option<PathBuf> {
if cfg!(target_os = "linux") && std::env::var_os("XDG_DATA_HOME").is_none() && std::env::var_os("HOME").is_none() {
return None;
}
dirs::data_dir()
} Prevention
- Launch the app from a normal login shell or set HOME explicitly in service/container units
- For headless/CI runs, set XDG_DATA_HOME to a writable temp directory
- Handle the None case with an actionable message naming the missing environment variable
When it happens
Trigger: Launching Graphite with HOME unset or empty (systemd service, cron job, minimal Docker container); XDG_DATA_HOME set to an empty string; a Windows session where SHGetKnownFolderPath fails; env vars stripped by a test harness or launcher.
Common situations: Running the desktop app from a daemon/service context or CI container that does not inherit a user environment; docker run without a HOME or with env cleared; SSH sessions with unusual PAM configurations.
Related errors
- Error setting Ctrl-C handler
- Failed to initialize on-disk resource storage
- Failed to create WGPU context
- InvalidData
- Failed to parse input type for #[implementation(...)]. Expec
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/b6f74c4fc7cd55a3.
Report an issue: GitHub.