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

cookie path unavailable

Error message

cookie path unavailable

What it means

write_netscape_for_anonymous in the omniget-core bilibili cookie module needs a filesystem path for the anonymous cookie file via cookie_path_for_account("bilibili.com", ANONYMOUS_SLUG). That helper returns None when it cannot derive a valid path (typically because the app data directory is unavailable on this platform). The function converts that None into an io::Error with the message "cookie path unavailable" rather than panicking.

Solutions

  1. Ensure the app data directory is resolvable: set HOME (Linux/macOS) or run in a normal user session so tauri/dirs can resolve app_data_dir.
  2. Check cookie_path_for_account for why it returns None (path resolver failing vs invalid slug) and add logging before the error.
  3. Initialize the cookie path eagerly at app startup (when the path resolver is guaranteed available) instead of lazily inside ensure_fresh.
  4. In tests, use tauri::test or dependency-inject a known cookie directory instead of relying on the platform resolver.

Example fix

// before
let path = crate::platforms::cookie_provider::cookie_path_for_account("bilibili.com", ANONYMOUS_SLUG)
    .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "cookie path unavailable"))?;

// after
let path = crate::platforms::cookie_provider::cookie_path_for_account("bilibili.com", ANONYMOUS_SLUG)
    .or_else(|| std::env::var_os("HOME").map(|h| std::path::PathBuf::from(h).join(".local/share/omniget/cookies/bilibili.com-anonymous.cookies")))
    .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "cookie path unavailable: app data dir could not be resolved"))?;
Defensive patterns

Strategy: fallback

Validate before calling

if crate::platforms::cookie_provider::cookie_path_for_account("bilibili.com", ANONYMOUS_SLUG).is_none() {
    // resolve fallback dir or disable anonymous cookie persistence
}

Try / catch

match write_netscape_for_anonymous(&state) {
    Err(e) if e.to_string().contains("cookie path unavailable") => {
        tracing::warn!("no cookie dir; continuing without persistence");
    }
    r => r?,
}

Prevention

When it happens

Trigger: ensure_fresh or bootstrap_anonymous calls write_netscape_for_anonymous while cookie_path_for_account returns None — i.e. the platform's app-data/data-local dir cannot be resolved (dirs crate returns None) or the account/slug components produce an invalid path.

Common situations: Running the Tauri app in a sandboxed or headless environment with no HOME/XDG_DATA_DIRS set; unusual OS packaging where tauri's path resolver fails; corrupt or misconfigured platform path resolution during CI test runs.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

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

    }
    if !state.bili_ticket.is_empty() {
        pairs.push(format!("bili_ticket={}", state.bili_ticket));
        pairs.push(format!("bili_ticket_expires={}", state.bili_ticket_expires));
    }
    pairs.push("CURRENT_FNVAL=4048".to_string());
    pairs.push("CURRENT_QUALITY=0".to_string());
    pairs.join("; ")
}

fn seed_cookie_header(state: &AnonymousCookieState) -> String {
    build_cookie_header(state)
}

fn write_netscape_for_anonymous(state: &AnonymousCookieState) -> std::io::Result<()> {
    let path =
        crate::platforms::cookie_provider::cookie_path_for_account("bilibili.com", ANONYMOUS_SLUG)
            .ok_or_else(|| {
                std::io::Error::new(std::io::ErrorKind::Other, "cookie path unavailable")
            })?;
    if let Some(parent) = path.parent() {
        std::fs::create_dir_all(parent)?;
    }
    let session_expires = now_secs() + 86400;
    let expires = if state.bili_ticket_expires > 0 {
        state.bili_ticket_expires
    } else {
        session_expires
    };
    let mut content = String::from("# Netscape HTTP Cookie File\n");
    let pairs: Vec<(&str, String)> = vec![
        ("_uuid", state.uuid.clone()),
        ("b_lsid", state.b_lsid.clone()),
        ("b_nut", state.b_nut.clone()),
        ("buvid_fp", state.buvid_fp.clone()),
        ("buvid3", state.buvid3.clone()),
        ("buvid4", state.buvid4.clone()),

View on GitHub (pinned to 8600b91f42)