tonhowtf/omniget · error
X: HTTP
Error message
X: HTTP {} {} What it means
post_json_raw received a non-2xx, non-429 HTTP status from the raw JSON POST endpoint. The client returns the status plus the first 300 chars of the response body as a single error string ('X: HTTP <status> <body-snippet>') since raw endpoints have no structured error contract.
Solutions
- Read the status and body snippet in the error to identify 401/403 (re-login) vs 400 (fix payload) vs 5xx (retry later)
- Refresh the X session (re-login for fresh auth_token/ct0) if the status is 401/403
- Compare the request body against X's current raw-endpoint contract and update fields
- Confirm the URL is still valid (endpoint not removed/renamed)
- Retry with backoff only for 5xx; 4xx responses will not succeed unchanged
Example fix
// before
let resp = client.post_json_raw(url, &body, &[]).await?;
// after
let resp = match client.post_json_raw(url, &body, &[]).await {
Err(e) if e.to_string().contains("HTTP 401") || e.to_string().contains("HTTP 403") => { relogin()?; client.post_json_raw(url, &body, &[]).await? }
r => r?,
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: sanity-check URL and session before the raw POST
url::Url::parse(url)?; // fail fast on malformed endpoints
if !client.authed() { relogin()?; } Try / catch
match client.post_json_raw(url, &body, &[]).await {
Err(e) => {
let s = e.to_string();
if s.contains("HTTP 401") || s.contains("HTTP 403") { relogin()?; client.post_json_raw(url, &body, &[]).await }
else if s.contains("HTTP 5") { /* retry with backoff */ }
else { Err(e) }
}
r => r,
} Prevention
- Keep the raw endpoint payload contract updated against X's current schema
- Validate the URL and content-type before sending
- Retry only 5xx; classify 4xx as payload/auth problems
- Capture the 300-char body snippet in logs for diagnosis
When it happens
Trigger: POSTing to a Grok/raw endpoint with an expired session (401/403), a bad payload the endpoint rejects (400), a removed endpoint (404), or server-side failure (5xx).
Common situations: Cookies expired before a Grok request; request body schema changed upstream (X shipped a new add_response.json contract); endpoint URL typo; X outage returning 5xx HTML pages.
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/b49bd86e56f0afd9.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/x/client.rs:495
HeaderValue::from_str(v),
) {
headers.insert(name, val);
}
}
let resp = self
.http
.post(url)
.headers(headers)
.json(body)
.send()
.await?;
if resp.status().as_u16() == 429 {
return Err(anyhow!("X_RATE_LIMIT:60"));
}
if !resp.status().is_success() {
let st = resp.status();
let text = resp.text().await.unwrap_or_default();
return Err(anyhow!(
"X: HTTP {} {}",
st,
text.chars().take(300).collect::<String>()
));
}
Ok(resp)
}
/// Pagina uma timeline: `on_page` recebe a resposta e devolve quantos
/// itens novos extraiu. Para no fim, no limite, em 3 paginas vazias, em
/// cursor repetido ou quando `job` for cancelado.
pub async fn paginate<F>(
&self,
op: &str,
mut variables: Value,
extra_features: Value,
limit: usize,
job: &str,View on GitHub (pinned to 8600b91f42)