tonhowtf/omniget · error

sem pasta de dados

Error message

sem pasta de dados

What it means

ai_keys::save persists the AI key list to a JSON file whose path comes from file() (ai_keys.rs:209); when the base data directory cannot be resolved, file() returns None and save fails with "sem pasta de dados" ("no data folder"). All writers (update, upsert, delete) funnel through save, so they all fail.

Solutions

  1. Run with a proper user session ($HOME set, writable config dir)
  2. Fix invalid XDG_CONFIG_HOME/XDG_DATA_HOME environment variables
  3. Pre-check file().is_some() before offering key-management features and degrade gracefully
  4. Add a fallback path when file() returns None

Example fix

// before
let p = file().ok_or_else(|| anyhow!("sem pasta de dados"))?;
// after
let p = file().or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".config/omniget/ai_keys.json")))
    .ok_or_else(|| anyhow!("sem pasta de dados"))?;
Defensive patterns

Strategy: fallback

Validate before calling

fn can_persist_keys() -> bool { file().is_some() && file().unwrap().parent().map(|p| p.exists() || std::fs::create_dir_all(p).is_ok()).unwrap_or(false) }

Try / catch

match upsert_key(entry).await {
    Err(e) if e.to_string() == "sem pasta de dados" => disable_key_ui_and_show_setup_hint(),
    other => handle(other),
}

Prevention

When it happens

Trigger: Any key mutation (update/upsert/delete) on a system where the directories provider cannot resolve the config/data dir — e.g. $HOME unset or invalid XDG env vars.

Common situations: Headless/test environments without a user profile; XDG_CONFIG_HOME set to a relative path; running the app under a service account.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/ai_keys.rs:221

}

// ── Armazenamento ──────────────────────────────────────────────────────

static LOCK: Mutex<()> = Mutex::new(());

fn file() -> Option<std::path::PathBuf> {
    super::tools_dir().map(|d| d.join("ai-keys.json"))
}

fn load() -> Vec<KeyEntry> {
    file()
        .and_then(|p| std::fs::read_to_string(p).ok())
        .and_then(|s| serde_json::from_str(&s).ok())
        .unwrap_or_default()
}

fn save(list: &[KeyEntry]) -> anyhow::Result<()> {
    let p = file().ok_or_else(|| anyhow!("sem pasta de dados"))?;
    std::fs::create_dir_all(p.parent().unwrap())?;
    let tmp = p.with_extension("json.tmp");
    std::fs::write(&tmp, serde_json::to_string_pretty(list)?)?;
    std::fs::rename(&tmp, &p)?;
    Ok(())
}

pub fn list() -> Vec<KeyView> {
    let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());
    load().iter().map(KeyEntry::view).collect()
}

/// Entrada completa (com segredo) para uso interno do app.
pub fn entry_with_secret(id: &str) -> anyhow::Result<KeyEntry> {
    get(id)
}

fn get(id: &str) -> anyhow::Result<KeyEntry> {

View on GitHub (pinned to 8600b91f42)