tonhowtf/omniget · error

tabela de precos: HTTP

Error message

tabela de precos: HTTP {}

What it means

When the cached price table is stale or unreadable, load() fetches it from the remote pricing source; if the HTTP response comes back but with a non-success status, it is wrapped as "tabela de precos: HTTP <status>". This distinguishes a reachable server returning an error code from a connection-level failure (which yields the 'indisponivel' variant instead).

Solutions

  1. Check the reported HTTP status: 429 means wait/backoff and retry; 5xx means retry later
  2. Verify the pricing endpoint URL hasn't changed (update the app if the upstream API moved)
  3. Force a refresh later (call with force=true) once the service recovers
  4. Check proxy/firewall rules if the status is 403

Example fix

// retry with backoff on 5xx/429
match other {
    Ok(r) if r.status().is_server_error() || r.status().as_u16() == 429 =>
        Err(anyhow!("tabela de precos: HTTP {} (retry later)", r.status())),
    Ok(r) => Err(anyhow!("tabela de precos: HTTP {}", r.status())),
    Err(e) => Err(anyhow!("tabela de precos indisponivel: {}", e)),
}
Defensive patterns

Strategy: retry

Try / catch

match pricing::info().await {
    Err(e) if e.to_string().contains("tabela de precos: HTTP") => {
        tokio::time::sleep(Duration::from_secs(30)).await;
        retry_with_backoff(3).await?; // 429/5xx são transientes
    }
    other => other?,
}

Prevention

When it happens

Trigger: load(force) or a stale-cache load where the pricing HTTP endpoint returns 4xx/5xx — endpoint moved, rate-limited (429), server error (500/503), or blocked by a proxy/gateway (403).

Common situations: Upstream pricing API deprecated its URL, temporary upstream outage, rate limiting after frequent refreshes, corporate proxy rejecting the request.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/pricing.rs:78

    match client.get(LITELLM_URL).send().await {
        Ok(resp) if resp.status().is_success() => {
            let text = resp.text().await?;
            let v: serde_json::Value = serde_json::from_str(&text)?;
            if let Some(parent) = path.parent() {
                std::fs::create_dir_all(parent)?;
            }
            tokio::fs::write(&path, &text).await?;
            Ok(v)
        }
        other => {
            // Sem rede: usa o que tiver em disco, mesmo velho.
            if let Ok(text) = tokio::fs::read_to_string(&path).await {
                if let Ok(v) = serde_json::from_str(&text) {
                    return Ok(v);
                }
            }
            match other {
                Ok(r) => Err(anyhow!("tabela de precos: HTTP {}", r.status())),
                Err(e) => Err(anyhow!("tabela de precos indisponivel: {}", e)),
            }
        }
    }
}

fn per_m(v: &serde_json::Value, key: &str) -> Option<f64> {
    v.get(key).and_then(|x| x.as_f64()).map(|x| x * 1_000_000.0)
}

fn to_price(key: &str, v: &serde_json::Value) -> ModelPrice {
    ModelPrice {
        key: key.to_string(),
        provider: v["litellm_provider"].as_str().unwrap_or("").to_string(),
        mode: v["mode"].as_str().unwrap_or("").to_string(),
        input_per_m: per_m(v, "input_cost_per_token"),
        output_per_m: per_m(v, "output_cost_per_token"),
        cache_read_per_m: per_m(v, "cache_read_input_token_cost"),

View on GitHub (pinned to 8600b91f42)