tonhowtf/omniget · error
X : resposta invalida ( )
Error message
X {}: resposta invalida ({}) What it means
After a successful HTTP status, check() parses the body as JSON; a serde failure raises 'X <op>: resposta invalida (<serde error>)', meaning X returned 2xx but the body is not valid JSON. It then also guards against a null/empty 'data' field as a separate no-data path.
Solutions
- Inspect the raw body — if it is HTML, X is challenging/blocking the client; slow down or authenticate.
- Log the first bytes of the response and the serde error to identify corruption or encoding issues.
- Ensure the request sets Accept: application/json and does not disable/miss decompression.
- Retry after backoff; challenge pages are often transient for flagged IPs.
Example fix
// before
let v: Value = serde_json::from_str(&text).map_err(|e| anyhow!("X {}: resposta invalida ({})", op, e))?;
// after
let v: Value = serde_json::from_str(&text).map_err(|e| {
tracing::warn!(op, snippet = %text.chars().take(120).collect::<String>(), "non-JSON 2xx from X");
anyhow!("X {}: resposta invalida ({})", op, e)
})?; Defensive patterns
Strategy: try-catch
Type guard
fn is_json(text: &str) -> bool {
serde_json::from_str::<serde_json::Value>(text).is_ok()
} Try / catch
match gql(op).await {
Err(e) if e.to_string().contains("resposta invalida") => {
// body was not JSON: likely a challenge page
slow_down_and_authenticate();
Err(e)
}
other => other,
} Prevention
- Send Accept: application/json and correct Accept-Encoding headers.
- Treat HTML-in-2xx as an anti-bot signal and reduce request rate.
- Log a body snippet with the parse error to distinguish challenge vs corruption.
- Prefer authenticated sessions, which receive fewer challenge pages.
When it happens
Trigger: check() getting a 2xx response whose body fails serde_json::from_str — HTML error/challenge pages, empty bodies, or BOM/compressed content mis-decoded as text.
Common situations: X serving an anti-bot challenge page with HTTP 200; captive portal or proxy injecting HTML; content-encoding mismatch causing garbled text.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- guest token ausente
- a resposta da API do TikTok não era JSON
- a API do TikTok devolveu resposta vazia — normalmente é a…
- a saída do gallery-dl não é um dump JSON válido
- Could not extract data from embed
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/4b01cfd7e3f6aec0.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/x/client.rs:322
return Err(anyhow!("X_RATE_LIMIT:{}", reset));
}
let text = resp.text().await.unwrap_or_default();
if status.as_u16() == 404 {
return Ok(Err("not_found".into()));
}
if status.as_u16() == 401 || status.as_u16() == 403 {
return Ok(Err(format!("auth:{}", status.as_u16())));
}
if !status.is_success() {
return Err(anyhow!(
"X {}: HTTP {} {}",
op,
status,
text.chars().take(200).collect::<String>()
));
}
let v: Value = serde_json::from_str(&text)
.map_err(|e| anyhow!("X {}: resposta invalida ({})", op, e))?;
if v.get("data")
.map(|d| d.is_null() || d.as_object().map(|o| o.is_empty()).unwrap_or(false))
.unwrap_or(true)
{
if let Some(msg) = v
.get("errors")
.and_then(|e| e.as_array())
.and_then(|a| a.first())
.and_then(|e| e.get("message"))
.and_then(|m| m.as_str())
{
if msg.contains("Query not found") || msg.contains("query_id") {
return Ok(Err("not_found".into()));
}
return Err(anyhow!("X {}: {}", op, msg));
}
}
Ok(Ok(v))View on GitHub (pinned to 8600b91f42)