tonhowtf/omniget · error

este provedor nao expoe saldo pela API

Error message

este provedor nao expoe saldo pela API

What it means

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.

Solutions

  1. Don't call balance for this provider; check balance manually on the provider's dashboard.
  2. Add a new match arm implementing the provider's balance endpoint in ai_keys.rs if it has one.
  3. Verify the entry's provider kind is set correctly — a mislabeled entry may fall into the catch-all.

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

// only call balance for kinds that support it
const BALANCE_KINDS: &[&str] = &["openrouter", "newapi" /* ...supported kinds */];
let entry = get(id)?;
if !BALANCE_KINDS.contains(&entry.kind.as_str()) {
    eprintln!("provider '{}' has no balance API — skip balance()", entry.kind);
}

Type guard

fn supports_balance(kind: &str) -> bool {
    matches!(kind, "openrouter" | "newapi")
}

Try / catch

match balance(id) {
    Ok(text) => show(text),
    Err(e) if e.to_string().contains("nao expoe saldo") => hide_balance_ui(),
    Err(e) => show_error(e),
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

                .bearer_auth(&entry.access_token)
                .header("New-Api-User", &entry.user_id)
                .send()
                .await?
                .error_for_status()?
                .json()
                .await?;
            if j["success"].as_bool() == Some(false) {
                return Err(anyhow!(
                    "{}",
                    j["message"].as_str().unwrap_or("painel recusou")
                ));
            }
            let d = &j["data"];
            let quota = d["quota"].as_f64().unwrap_or(0.0) / 500_000.0;
            let used = d["used_quota"].as_f64().unwrap_or(0.0) / 500_000.0;
            format!("{} ({} usados)", usd(quota), usd(used))
        }
        _ => return Err(anyhow!("este provedor nao expoe saldo pela API")),
    };
    update(id, |e| e.balance = Some(text))
}

// ── Exportar ───────────────────────────────────────────────────────────

fn is_openai_compatible(kind: &str) -> bool {
    !matches!(kind, "anthropic" | "gemini")
}

pub fn export(format: &str, ids: &[String]) -> anyhow::Result<String> {
    let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());
    let list: Vec<KeyEntry> = load()
        .into_iter()
        .filter(|e| ids.is_empty() || ids.contains(&e.id))
        .collect();
    if list.is_empty() {
        return Err(anyhow!("nenhuma chave selecionada"));

View on GitHub (pinned to 8600b91f42)