{"record":{"id":"d5eff83a62b593e7","repo":"tonhowtf/omniget","slug":"could-not-determine-data-directory-pricing","errorCode":null,"errorMessage":"Could not determine data directory","messagePattern":"Could not determine data directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pricing.rs","lineNumber":47,"sourceCode":"    pub supports_tools: bool,\n    pub supports_reasoning: bool,\n    pub supports_caching: bool,\n    pub deprecation_date: Option<String>,\n}\n\nfn cache_path() -> Option<PathBuf> {\n    super::tools_dir().map(|d| d.join(\"pricing\").join(\"litellm.json\"))\n}\n\n#[derive(Debug, Clone, Serialize)]\npub struct PricingInfo {\n    pub models: usize,\n    pub updated_at: Option<String>,\n    pub path: Option<String>,\n}\n\nasync fn load(force: bool) -> anyhow::Result<serde_json::Value> {\n    let path = cache_path().ok_or_else(|| anyhow!(\"Could not determine data directory\"))?;\n    let fresh = std::fs::metadata(&path)\n        .and_then(|m| m.modified())\n        .map(|t| t.elapsed().map(|e| e < MAX_AGE).unwrap_or(false))\n        .unwrap_or(false);\n    if !force && fresh {\n        if let Ok(text) = tokio::fs::read_to_string(&path).await {\n            if let Ok(v) = serde_json::from_str(&text) {\n                return Ok(v);\n            }\n        }\n    }\n    let client = super::client()?;\n    match client.get(LITELLM_URL).send().await {\n        Ok(resp) if resp.status().is_success() => {\n            let text = resp.text().await?;\n            let v: serde_json::Value = serde_json::from_str(&text)?;\n            if let Some(parent) = path.parent() {\n                std::fs::create_dir_all(parent)?;","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pricing.rs#L29-L65","documentation":"The pricing module caches the model price table in the platform data directory; cache_path() returns Option and is None when no data directory can be resolved (e.g. no HOME/XDG dir on Linux, missing APPDATA on Windows). load() converts that None into this error before even attempting a fetch. All public entry points (info, search, price_for) go through load, so they all fail in this state.","triggerScenarios":"Calling info, search, or price_for on a system where dirs-style data-dir resolution fails: running as a service without HOME set, container images with no user profile, or exotic platforms the directory library doesn't support.","commonSituations":"CI runners or systemd units running without HOME, Docker containers running as root with no XDG_DATA_HOME, misconfigured environment after su/sudo.","solutions":["Set HOME (Linux/macOS) or APPDATA/LOCALAPPDATA (Windows) to a writable directory","Set an explicit XDG_DATA_HOME to a writable path","Ensure the process runs as a user with a real profile directory","Run the app outside restricted service contexts or pass a configured data dir"],"exampleFix":"// before: failing under systemd\nExecStart=/opt/app/omniget\n// after\nEnvironment=HOME=/var/lib/omniget\nExecStart=/opt/app/omniget","handlingStrategy":"validation","validationCode":"// check a resolvable data dir before calling the API\nlet ok = std::env::var(\"HOME\").is_ok()\n    || std::env::var(\"XDG_DATA_HOME\").is_ok()\n    || std::env::var(\"APPDATA\").is_ok();\nif !ok { eprintln!(\"defina HOME ou XDG_DATA_HOME\"); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set HOME (or XDG_DATA_HOME) for services, cron jobs and containers","Run daemons under a real user account with a writable profile","Document required env vars for headless deployments"],"tags":["config","data-directory","environment","rust"],"backgroundTag":"missing-env-var","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}