tonhowtf/omniget · error · std::io::Error

app_data_dir unavailable

Error message

app_data_dir unavailable

What it means

save_state persists bilibili anonymous cookie state by first resolving meta_file_path(), which is based on the app data directory. When the app data dir cannot be resolved it raises this io::Error (Kind::Other). Called from bootstrap_anonymous, this aborts anonymous-cookie bootstrapping since state cannot be written.

Solutions

  1. Set HOME (Linux/macOS) so the app data dir can be resolved, then retry bootstrap_anonymous.
  2. Ensure XDG_DATA_HOME/XDG_CONFIG_HOME are set if the paths helper uses them.
  3. Wrap save_state failures in bootstrap_anonymous so bootstrapping degrades gracefully instead of hard-failing.
  4. Run within a normal user session rather than a service account.

Example fix

// service launch fix
Environment=HOME=/home/omniget
XDG_DATA_HOME=/home/omniget/.local/share
# or in code
let state = AnonymousCookieState::default();
save_state(&state).map_err(|e| log::warn!("cookie state not saved: {e}")).unwrap_or(());
Defensive patterns

Strategy: try-catch

Validate before calling

let app_data_ok = std::env::var("HOME").is_ok()
    || std::env::var("XDG_DATA_HOME").is_ok();
if !app_data_ok { eprintln!("cannot resolve app data dir; set HOME"); }

Try / catch

match save_state(&state) {
    Err(e) if e.to_string().contains("app_data_dir unavailable") => {
        log::warn!("skipping cookie persistence: {e}"); // continue anonymous
    }
    Err(e) => return Err(e.into()),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling save_state (directly or via bootstrap_anonymous) on a system where the app data dir lookup returns None — e.g. Linux with HOME unset when computing the config/data dir, or a platform not supported by the dirs helper.

Common situations: Running the app in a container/service without HOME; first-run bootstrap in a headless environment; portable-style launches where the app-data resolution helper fails.

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


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/202d7237592b3555. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/bilibili/cookie.rs:64

        crate::platforms::cookie_provider::cookie_path_for_account("bilibili.com", ANONYMOUS_SLUG)?;
    Some(cookie_path.with_file_name("_anonymous_meta.json"))
}

pub fn load_state() -> AnonymousCookieState {
    let path = match meta_file_path() {
        Some(p) => p,
        None => return AnonymousCookieState::default(),
    };
    let content = match std::fs::read_to_string(&path) {
        Ok(c) => c,
        Err(_) => return AnonymousCookieState::default(),
    };
    serde_json::from_str(&content).unwrap_or_default()
}

pub fn save_state(state: &AnonymousCookieState) -> std::io::Result<()> {
    let path = meta_file_path().ok_or_else(|| {
        std::io::Error::new(std::io::ErrorKind::Other, "app_data_dir unavailable")
    })?;
    if let Some(parent) = path.parent() {
        std::fs::create_dir_all(parent)?;
    }
    let serialized = serde_json::to_string_pretty(state)
        .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?;
    std::fs::write(path, serialized)
}

pub async fn ensure_fresh() -> Result<AnonymousCookieState> {
    let cached = load_state();
    if cached.is_fresh() {
        write_netscape_for_anonymous(&cached).ok();
        return Ok(cached);
    }
    bootstrap_anonymous().await
}

View on GitHub (pinned to 8600b91f42)