tonhowtf/omniget · error
X : HTTP
Error message
X {}: HTTP {} {} What it means
Catch-all for non-success X API responses that are not 404 (treated as not_found) or 401/403 (treated as auth errors): the client errors with 'X <op>: HTTP <status> <first-200-chars-of-body>', giving the failing operation name plus a truncated body for diagnosis.
Solutions
- Read the truncated body in the message — it usually names the exact problem (bad request field, blocked op).
- Retry on 5xx with backoff; treat 400 as a bug in the query variables you pass.
- Verify the GraphQL operation/queryId is current — X rotates these and stale ones fail.
- Check X status/incident reports if 5xx persists across operations.
Example fix
// before
client.gql_get("TweetDetail", &vars).await?; // fails: X TweetDetail: HTTP 400 {"errors":...}
// after
let v = client.gql_get("TweetDetail", &vars).await
.map_err(|e| { tracing::error!(op = "TweetDetail", err = %e, "x gql failed"); e })?; Defensive patterns
Strategy: try-catch
Try / catch
match client.gql_get(op, &q).await {
Err(e) if e.to_string().starts_with("X ") && e.to_string().contains("HTTP 5") => {
backoff_retry(op, max_attempts = 3)
}
Err(e) => Err(e),
ok => ok,
} Prevention
- Retry only transient statuses (5xx, 408) with exponential backoff.
- Keep GraphQL operation IDs/queryIds up to date with X's current API.
- Log the op name and truncated body included in the error for triage.
- Validate request variables before sending to avoid 400s.
When it happens
Trigger: check() receives statuses like 400, 404-as-unexpected, 5xx, or 429-adjacent errors outside the special-cased codes while executing a GraphQL op named in the message.
Common situations: X server errors (5xx) or maintenance; malformed query variables causing 400 Bad Request; deprecated GraphQL endpoints returning unexpected statuses after X API changes.
Related errors
- Twitch GQL respondeu HTTP
- o Goodreads respondeu HTTP
- X nao entregou guest token: HTTP
- Instagram GQL retornou HTTP
- Twitter API retornou HTTP
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/bb2445171478a74a.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/x/client.rs:314
if status.as_u16() == 429 {
let reset = resp
.headers()
.get("x-rate-limit-reset")
.and_then(|v| v.to_str().ok())
.and_then(|v| v.parse::<i64>().ok())
.map(|r| (r - chrono::Utc::now().timestamp()).max(1))
.unwrap_or(900);
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())View on GitHub (pinned to 8600b91f42)