tonhowtf/omniget · error
FxTwitter: resposta invalida
Error message
FxTwitter: resposta invalida ({}) What it means
fx.rs's get() calls the FxTwitter API and this error is raised when the HTTP response body cannot be deserialized as JSON. It wraps the serde error message plus the raw payload interpretation, meaning the upstream service returned non-JSON (HTML error page, empty body, gateway error).
Solutions
- Retry the request; transient upstream outages are the usual cause.
- Log the response text and status before parsing to identify what actually came back.
- Check FxTwitter service status / try an alternate API host (e.g. api.fxtwitter.com vs fixupx).
- Fall back to a different X data source (the native X client) when FxTwitter is unavailable.
Example fix
// before
let body: Value = resp.json().await
.map_err(|e| anyhow!("FxTwitter: resposta invalida ({})", e))?;
// after
let text = resp.text().await?;
let body: Value = serde_json::from_str(&text)
.map_err(|e| anyhow!("FxTwitter: resposta invalida ({}) corpo: {:.200}", e, text))?; Defensive patterns
Strategy: fallback
Type guard
fn is_json_content(headers: &reqwest::header::HeaderMap) -> bool {
headers.get(reqwest::header::CONTENT_TYPE)
.and_then(|v| v.to_str().ok())
.map_or(false, |v| v.contains("application/json"))
} Try / catch
match fx::status(&id).await {
Ok(p) => p,
Err(e) if e.to_string().starts_with("FxTwitter: resposta invalida") => {
eprintln!("FxTwitter fora do ar, usando cliente nativo");
xclient::status(&id).await?
}
Err(e) => return Err(e),
} Prevention
- Check Content-Type is application/json before parsing
- Keep the native X client as a documented fallback path
- Alert on consecutive non-JSON responses (indicates upstream outage)
- Use a short request timeout so proxy error pages fail fast
When it happens
Trigger: FxTwitter (or an intermediate proxy/CDN) responds with HTML (502/503 Cloudflare page), an empty body, or truncated output so resp.json() fails during any get()-backed call: status, thread, conversation, profile, profile_statuses, profile_media.
Common situations: FxTwitter outage or Cloudflare challenge page; corporate proxy stripping/rewriting the response; network device injecting a captive-portal page; FxTwitter deployment returning text/plain errors.
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
- Pinterest respondeu HTTP
- o Reddit respondeu algo que não é JSON
- LibreTranslate: resposta invalida
- YouTube não retornou URL
- HTTP fetching playlist
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/79444c228facebc4.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/x/fx.rs:46
async fn get(path: &str, query: &[(&str, String)]) -> anyhow::Result<Value> {
let client = client()?;
let url = format!("{}/{}", BASE, path.trim_start_matches('/'));
let mut req = client.get(&url);
let q: Vec<(&str, &str)> = query
.iter()
.filter(|(_, v)| !v.is_empty())
.map(|(k, v)| (*k, v.as_str()))
.collect();
if !q.is_empty() {
req = req.query(&q);
}
let resp = req.send().await?;
let status = resp.status();
let body: Value = resp
.json()
.await
.map_err(|e| anyhow!("FxTwitter: resposta invalida ({})", e))?;
let code = body
.get("code")
.and_then(|c| c.as_u64())
.unwrap_or(status.as_u16() as u64);
if code == 404 {
return Err(anyhow!("nao encontrado no X (ou o post e privado)"));
}
if code == 401 {
return Err(anyhow!("post ou perfil privado"));
}
if code == 429 {
return Err(anyhow!(
"FxTwitter: limite de requisicoes atingido, tente de novo em instantes"
));
}
if code >= 400 {
let msg = body
.get("message")View on GitHub (pinned to 8600b91f42)