sxyazi/yazi · critical

Failed to get state directory

Error message

Failed to get state directory

What it means

Same OnceLock-cached resolution but for the state directory; on Windows it calls dirs::data_dir() and panics if None. dirs::data_dir() resolves %APPDATA% (Roaming), so None means APPDATA/USERPROFILE are missing. Yazi requires a state location, so this is an unrecoverable panic at first access.

Solutions

  1. Set APPDATA to an absolute path (e.g. %USERPROFILE%\AppData\Roaming) before launch
  2. Ensure USERPROFILE is set for the account running yazi
  3. Run yazi from an interactive user shell rather than a service context

Example fix

// before
runas /user:svc yazi.exe
// after
set "APPDATA=C:\Users\svc\AppData\Roaming"
runas /user:svc /env yazi.exe
Defensive patterns

Strategy: validation

Validate before calling

if [ -z "$APPDATA" ] && [ -n "$USERPROFILE" ]; then export APPDATA="$USERPROFILE/AppData/Roaming"; fi

Prevention

When it happens

Trigger: First access of the yazi_fs xdg state_dir on Windows when dirs::data_dir() returns None (APPDATA or USERPROFILE env vars unset).

Common situations: Launching yazi from a scheduler/service or a shell with sanitized environment on Windows; broken roaming profile configuration.

Related errors


AI-assisted analysis of sxyazi/yazi@a541adde4e (2026-09-02). Data as JSON: /api/errors/748364828b0cd7ee. Report an issue: GitHub.

Appendix: source

Thrown at yazi-fs/src/xdg.rs:72

		{
			env::var_os("XDG_CACHE_HOME")
				.map(PathBuf::from)
				.filter(|p| p.is_absolute())
				.map(|p| p.join("yazi"))
				.or_else(|| dirs::home_dir().map(|h| h.join(".cache/yazi")))
				.expect("Failed to get asset directory")
		}
	}

	pub fn state_dir() -> &'static PathBuf {
		static DIR: LazyLock<PathBuf> = LazyLock::new(Xdg::load_state_dir);
		&DIR
	}

	fn load_state_dir() -> PathBuf {
		#[cfg(windows)]
		{
			dirs::data_dir().map(|p| p.join("yazi\\state")).expect("Failed to get state directory")
		}
		#[cfg(unix)]
		{
			env::var_os("XDG_STATE_HOME")
				.map(PathBuf::from)
				.filter(|p| p.is_absolute())
				.map(|p| p.join("yazi"))
				.or_else(|| dirs::home_dir().map(|h| h.join(".local/state/yazi")))
				.expect("Failed to get state directory")
		}
	}

	pub fn runtime_dir() -> &'static PathBuf {
		static DIR: LazyLock<PathBuf> = LazyLock::new(Xdg::load_runtime_dir);
		&DIR
	}

	fn load_runtime_dir() -> PathBuf {

View on GitHub (pinned to a541adde4e)