{"record":{"id":"c70def1b4e295085","repo":"tonhowtf/omniget","slug":"este-provedor-nao-expoe-saldo-pela-api","errorCode":null,"errorMessage":"este provedor nao expoe saldo pela API","messagePattern":"este provedor nao expoe saldo pela API","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/ai_keys.rs","lineNumber":501,"sourceCode":"                .bearer_auth(&entry.access_token)\n                .header(\"New-Api-User\", &entry.user_id)\n                .send()\n                .await?\n                .error_for_status()?\n                .json()\n                .await?;\n            if j[\"success\"].as_bool() == Some(false) {\n                return Err(anyhow!(\n                    \"{}\",\n                    j[\"message\"].as_str().unwrap_or(\"painel recusou\")\n                ));\n            }\n            let d = &j[\"data\"];\n            let quota = d[\"quota\"].as_f64().unwrap_or(0.0) / 500_000.0;\n            let used = d[\"used_quota\"].as_f64().unwrap_or(0.0) / 500_000.0;\n            format!(\"{} ({} usados)\", usd(quota), usd(used))\n        }\n        _ => return Err(anyhow!(\"este provedor nao expoe saldo pela API\")),\n    };\n    update(id, |e| e.balance = Some(text))\n}\n\n// ── Exportar ───────────────────────────────────────────────────────────\n\nfn is_openai_compatible(kind: &str) -> bool {\n    !matches!(kind, \"anthropic\" | \"gemini\")\n}\n\npub fn export(format: &str, ids: &[String]) -> anyhow::Result<String> {\n    let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());\n    let list: Vec<KeyEntry> = load()\n        .into_iter()\n        .filter(|e| ids.is_empty() || ids.contains(&e.id))\n        .collect();\n    if list.is_empty() {\n        return Err(anyhow!(\"nenhuma chave selecionada\"));","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/ai_keys.rs#L483-L519","documentation":"balance() matches the provider kind against a fixed set of providers with balance APIs; the catch-all arm throws this error meaning the provider type does not expose balance retrieval through its API. It is a static unsupported-provider condition, not a network or credential failure.","triggerScenarios":"Calling balance(id) on a key entry whose provider kind is not one of the implemented kinds (e.g. generic/custom OpenAI-compatible endpoints or providers without a balance route).","commonSituations":"User adds a custom OpenAI-compatible endpoint and expects balance lookup; provider genuinely has no balance API (many aggregators do not); provider kind misclassified during entry creation.","solutions":["Don't call balance for this provider; check balance manually on the provider's dashboard.","Add a new match arm implementing the provider's balance endpoint in ai_keys.rs if it has one.","Verify the entry's provider kind is set correctly — a mislabeled entry may fall into the catch-all."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"// only call balance for kinds that support it\nconst BALANCE_KINDS: &[&str] = &[\"openrouter\", \"newapi\" /* ...supported kinds */];\nlet entry = get(id)?;\nif !BALANCE_KINDS.contains(&entry.kind.as_str()) {\n    eprintln!(\"provider '{}' has no balance API — skip balance()\", entry.kind);\n}","typeGuard":"fn supports_balance(kind: &str) -> bool {\n    matches!(kind, \"openrouter\" | \"newapi\")\n}","tryCatchPattern":"match balance(id) {\n    Ok(text) => show(text),\n    Err(e) if e.to_string().contains(\"nao expoe saldo\") => hide_balance_ui(),\n    Err(e) => show_error(e),\n}","preventionTips":["Gate the balance button in the UI by provider kind","Check the provider's docs for a balance endpoint before expecting one","Hide/disable balance queries for generic OpenAI-compatible endpoints","Extend the match in ai_keys.rs when a provider adds a balance API"],"tags":["unsupported-operation","api"],"backgroundTag":"unsupported-operation","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}