tonhowtf/omniget · error
tabela de precos invalida
Error message
tabela de precos invalida
What it means
search() loads the price table (from cache or network) and requires the top-level JSON to be an object keyed by model name. If the parsed value is not a JSON object (array, string, null, etc.), it throws "tabela de precos invalida". This is a schema guard protecting the token-matching logic that iterates over object keys.
Solutions
- Delete the cached pricing file at cache_path so load() re-fetches a fresh table
- Validate the JSON structure of the cache file (top-level must be an object of model keys)
- Update the app if the upstream price-table format changed
- Add a shape check in load() before caching responses
Example fix
// before: trusting any parseable JSON
if let Ok(text) = tokio::fs::read_to_string(&path).await {
if let Ok(v) = serde_json::from_str(&text) { return Ok(v); }
}
// after: validate shape before returning
if let Ok(text) = tokio::fs::read_to_string(&path).await {
if let Ok(v) = serde_json::from_str::<serde_json::Value>(&text) {
if v.as_object().map(|o| !o.is_empty()).unwrap_or(false) { return Ok(v); }
}
} Defensive patterns
Strategy: type-guard
Validate before calling
// inspect the cache before use
let v: serde_json::Value = serde_json::from_str(
&std::fs::read_to_string(&cache_path)?
)?;
if !v.is_object() {
std::fs::remove_file(&cache_path)?; // força re-fetch
} Type guard
fn is_price_table(v: &serde_json::Value) -> bool {
v.as_object().map(|o| !o.is_empty()).unwrap_or(false)
} Try / catch
match pricing::search(q, "", 10).await {
Err(e) if e.to_string().contains("invalida") => {
// limpar cache e tentar uma vez
std::fs::remove_file(cache_path()).ok();
pricing::search(q, "", 10).await
}
other => other,
} Prevention
- Validate the shape of fetched data before writing it to the cache
- Write the cache atomically (temp file + rename) to avoid truncated files
- Delete stale caches after app upgrades that change the schema
When it happens
Trigger: The cached pricing.json contains valid JSON of the wrong shape (e.g. truncated into an array, an HTML error page saved as the cache, or an upstream format change), and load() successfully parsed it without shape-checking.
Common situations: Cache file corrupted or half-written by a crash, upstream changed the response schema, a proxy returned an error page that was cached as JSON text (if it happened to parse).
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- tabela de precos: HTTP
- tabela de precos indisponivel
- LibreTranslate: resposta invalida
- a resposta da API do TikTok não era JSON
- yt-dlp returned invalid JSON
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/78822a08fe643476.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/pricing.rs:133
.and_then(|p| std::fs::metadata(p).ok())
.and_then(|m| m.modified().ok())
.map(|t| chrono::DateTime::<chrono::Utc>::from(t).to_rfc3339());
Ok(PricingInfo {
models: v
.as_object()
.map(|o| o.len().saturating_sub(1))
.unwrap_or(0),
updated_at: updated,
path: path.map(|p| p.to_string_lossy().to_string()),
})
}
/// Busca por substring nas chaves; todas as palavras precisam bater.
pub async fn search(query: &str, mode: &str, limit: usize) -> anyhow::Result<Vec<ModelPrice>> {
let v = load(false).await?;
let obj = v
.as_object()
.ok_or_else(|| anyhow!("tabela de precos invalida"))?;
let tokens: Vec<String> = query
.to_lowercase()
.split_whitespace()
.map(|s| s.to_string())
.collect();
let mut out: Vec<ModelPrice> = obj
.iter()
.filter(|(k, _)| *k != "sample_spec")
.filter(|(k, val)| {
let hay = format!(
"{} {}",
k.to_lowercase(),
val["litellm_provider"]
.as_str()
.unwrap_or("")
.to_lowercase()
);
tokens.iter().all(|t| hay.contains(t))View on GitHub (pinned to 8600b91f42)