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

  1. Set a valid HOME (or XDG_DATA_HOME) in the process environment: docker -e HOME=/home/user or Environment=HOME=... in the service unit
  2. Verify with env | grep -E 'HOME|XDG_DATA_HOME' from the same launcher context
  3. Fix the launcher/shell profile that strips environment variables
  4. 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

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


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/b6f74c4fc7cd55a3. Report an issue: GitHub.